Unexpected physical mode in a SpriteKit scene

I am implementing the mass-w760 system (many small physical bodies connected together with SKPhysicsJointSpring instances) using SpriteKit. Some particles will catch on going through the center of the scene.

There seems to be a small, static body in the middle of the scene, and I don't know why it is there.

Here is an easy way to see what I'm talking about:

  • In Xcode 8, create a new project with a Game template.
  • In GameViewController.viewDidLoad() add view.showsPhysics = true

If you run the project, you will see a small dot in the middle, which is an erroneous body:

enter image description here

Does anyone know how to get rid of it?

Edit: I tried to manually create a scene object:

In GameViewController.viewDidLoad() I replaced this:

 // Load the SKScene from 'GameScene.sks' if let scene = SKScene(fileNamed: "GameScene") { view.presentScene(scene) } 

with this:

 let scene = GameScene(size: view.frame.size) scene.anchorPoint = CGPoint(x: 0.5, y: 0.5) view.presentScene(scene) 

but it doesn’t fix it.

+5
source share
3 answers

About the hello world game template, xCode seems a bit physicsBody related to the GameScene node. With some code, I found this:

 class GameScene: SKScene { private var label : SKLabelNode? private var spinnyNode : SKShapeNode? override func didMove(to view: SKView) { ... // End part of this function: if let b = physicsWorld.body(in: (label?.frame)!) { if let node = b.node { print("Type of this node: \(type(of:node))") print("Frame of this node: \(node.frame))") } print("Area covered by this node physicsBody: \(b.area)") } } } 

enter image description here

With a breakpoint to the last curly brace, you can see two bodies (possibly an array of bodies), one of which is physicsBody in the left debugArea (array with index 1 ) with the same hexadecimal address as my body b in my code: 0x79794f90 , a small rectangle with an area of ​​4.444

 Printing description of ((PKPhysicsBody *)0x79794f90): <SKPhysicsBody> type:<Rectangle> representedObject:[<SKScene> name:'(null)' frame:{{-375, -667}, {750, 1334}} anchor:{0.5, 0.5}] (lldb) 

enter image description here

+2
source

In any case, I decided to answer because the comments are not suitable due to the large amount of information that I want to share. Unfortunately, my answer, unfortunately, does not answer the question, but it gives some useful information about this unidentified, obviously capable of flying (physical object) :)

So this is the code how to capture it (and change it ???):

  //you can use self.frame here...I just copied Alessandro code self.physicsWorld.enumerateBodies(in:(label?.frame)!) { body, stop in if let node = body.node { print("Type of this node: \(type(of:node))") print("Frame of this node: \(node.frame))") }else{ print("This body node property is nil") body.affectedByGravity = true body.isDynamic = true body.applyImpulse(CGVector(dx: 0.003, dy: 0.0003)) } print("Area covered by this node physicsBody: \(body.area)") } 

So, if you set a breakpoint inside this else statement, you can completely scan this physical body and get all the information about it, for example, that the node property is set to nil or that the isDynamic property isDynamic set to false . But you can change this, and, as in my code, set the isDynamics example to true. This makes it movable. Therefore, if you apply any forces to it, it will move.

However, as I said in the comments, I have no idea why it is and what it represents or what its purpose is.

In addition, for those who are wondering how it is possible that one physical body does not have a node associated with it ( body.node equals nil ), but is still displayed on the screen when showsPhysics set to true , there is a reasonable explanation. The world of physics is separated from the node tree. Therefore, we can remove the sprite from the node tree, but this does not mean that its physical body will be immediately deleted. It may happen that the physics engine has not finished modeling ... So you probably wonder how this can happen?

Let's say you have three SKSpriteNode objects intersecting at the same time (for example, A contacts B and A contacts C at the same time). SpriteKit can only handle one contact per time. And say that you remove A from the parent when it contacts B. Then there is contact between A and C, so didBegin:(_ contact) will be called twice. And if you remove A from your parent on the first call to didBegin(_ contact) , the next call to didBegin(_ contact) bodyA.node will be nil ( bodyA is the physical body of sprite A), but its physical body will remain visible until the engine finishes what it takes. This is because the node tree and the world of physics are separate.

+2
source

I had a similar problem. I have a game with two sprite nodes connected together (SKPhysicsJointFixed.joint) moving around the created SKEditor scene. According to my design, this node-pair would act on the third sprite node and smoothly move away from the third sprite node, EXCLUDES when the blow was in the center of the scene. For the scene’s center of impact, the pair node will be compressed together, being dropped from the third node sprite, representing a poor graphic.

After much debugging of my code, I found this post. Kudos to the explanation and code. I can’t answer the question “why”, but the question is about how “particles will be deceived when going around the center of the scene”, my suggested solution is to clear collisionBitMask instead of moving the body.

BTWBitMask category at boot 0.

  //moves the problem offscreen unless it hits another node //body.affectedByGravity = true //body.isDynamic = true //body.applyImpulse(CGVector(dx: 0.003, dy: 0.0003)) // // collisionBitMask loads with 4294967295 = default value to collide with all categories // body.collisionBitMask = 0 
+1
source

Source: https://habr.com/ru/post/1262224/


All Articles