swift - SKshapenode no responde a Physicsbody
sprite-kit skphysicsbody (2)
He creado un SKShapeNode
y le he asignado un physicsBody
. Sin embargo, no se activa cuando hay contacto.
Creación del código SKShapeNode
:
-(SKShapeNode*)gravityline{
//SKSpriteNode *lolo=[[SKSpriteNode alloc]init];
SKShapeNode *lolo = [[SKShapeNode alloc] init];
CGPoint fff=CGPointMake(ray1.position.x, ray1.position.y);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, fff.x, fff.y);
CGPathAddLineToPoint(path, 0,rayoriginpoint.x,rayoriginpoint.y );
CGPathCloseSubpath(path);
lolo.path = path;
lolo.name=@"gravityline";
lolo.strokeColor=[SKColor greenColor];
lolo.glowWidth=.1;
CGPathRelease(path);
lolo.physicsBody=[SKPhysicsBody bodyWithEdgeFromPoint:fff toPoint:rayoriginpoint];
//lolo.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromPath:path];
//lolo.physicsBody=[SKPhysicsBody bodyWithPolygonFromPath:path];
lolo.physicsBody.categoryBitMask=raylightCategory;
lolo.physicsBody.collisionBitMask=batCategory;
lolo.physicsBody.contactTestBitMask=batCategory;
lolo.physicsBody.usesPreciseCollisionDetection=YES;
lolo.physicsBody.linearDamping=0;
lolo.physicsBody.restitution=1.0;
lolo.physicsBody.dynamic=NO;
return lolo;
}
Aquí está el código trigering:
- (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 == raylightCategory && secondBody.categoryBitMask==batCategory)
{
NSLog(@"Contact with bat have been made");
[secondBody.node removeFromParent];
}
}
Si alguien tiene una pista de lo que hice mal, ¿por qué SKShapeNode
no está activando PhysicsBody, por favor avíseme.
Esto ciertamente no funcionará:
lolo.physicsBody=[SKPhysicsBody bodyWithEdgeFromPoint:fff toPoint:rayoriginpoint];
En todo caso, devolverá un cuerpo ya asignado a un nodo diferente. Pero supongo que simplemente devuelve nada.
Esta línea comentada tampoco funcionará:
//lolo.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromPath:path];
Las formas de los bordes crearán cuerpos estáticos (como en: inmuebles). Por lo tanto, este nodo no se moverá a través de la física y, si no me equivoco, tampoco recibirás respuesta de contacto de cuerpos estáticos, solo cuerpos dinámicos.
Este debería funcionar:
//lolo.physicsBody=[SKPhysicsBody bodyWithPolygonFromPath:path];
Pero luego estás configurando el cuerpo en un cuerpo estático aquí:
lolo.physicsBody.dynamic=NO;
Por lo tanto, se aplican las mismas reglas que si estuviera creando un cuerpo con un bucle de borde.
Su código no muestra exactamente con qué está colisionando su "gravityLine". Solo puedo especular por su descripción que no está detectando una colisión con un objeto de forma redonda (una bola y un bate).
El método "gravityLine" parece devolver un SKShapeNode definido por una forma basada en el borde:
lolo.physicsBody=[SKPhysicsBody bodyWithEdgeFromPoint:fff toPoint:rayoriginpoint];
Cuando se trata de colisiones, es importante leer la Guía de programación del kit de Sprite de Apple, específicamente su explicación de tres tipos de formas.
1) Un volumen dinámico simula un objeto físico con volumen y masa que puede verse afectado por fuerzas y colisiones en el sistema. Use volúmenes dinámicos para representar elementos en la escena que necesitan moverse y colisionar entre sí.
2) Un volumen estático es similar a un volumen dinámico, pero su velocidad se ignora y no se ve afectada por fuerzas o colisiones. Sin embargo, debido a que todavía tiene volumen, otros objetos pueden rebotar o interactuar con él. Use volúmenes estáticos para representar elementos que ocupen espacio en la escena, pero la simulación no debe moverlos. Por ejemplo, puede usar volúmenes estáticos para representar las paredes de un laberinto. Si bien es útil pensar en los volúmenes estáticos y dinámicos como entidades distintas, en la práctica estos son dos modos diferentes que puede aplicar a cualquier cuerpo de física basado en el volumen. Esto puede ser útil porque puede activar o desactivar selectivamente los efectos para un cuerpo.
3) Un borde es un cuerpo estático sin volumen. Los bordes nunca son movidos por la simulación y su masa no importa. Los bordes se utilizan para representar el espacio negativo dentro de una escena (como un punto hueco dentro de otra entidad) o un límite infranqueable e invisible. Por ejemplo, los bordes se utilizan con frecuencia para representar los límites de su escena. La principal diferencia entre un borde y un volumen es que un borde permite el movimiento dentro de sus propios límites, mientras que un volumen se considera un objeto sólido. Si los bordes se mueven por otros medios, solo interactúan con volúmenes, no con otros bordes.
Según la información anterior, si lee la documentación del método que utilizó bodyWithEdgeFromPoint: toPoint:, verá que está creando un cuerpo de física "basado en el borde".
Valor de retorno
Un nuevo cuerpo de física basado en los bordes.
Discusión
Un borde no tiene volumen o masa y siempre se trata como si la propiedad dinámica fuera igual a NO. Los bordes solo pueden colisionar con cuerpos de física basados en volumen.
Para que funcione su colisión, debe asegurarse de que su borde esté colisionando con un cuerpo de física basado en el volumen. Cada método de creación de forma física del cuerpo documenta qué tipo de forma está creando.
Si está utilizando un cuerpo de física basado en el volumen que está colisionando con su borde, entonces otra posibilidad puede deberse al tamaño o la velocidad de los objetos involucrados. De nuevo, leer los documentos de Apple lo deja en claro.
Especifique las colisiones de alta precisión para objetos pequeños o de movimiento rápido: cuando el Kit Sprite realiza la detección de colisión, primero determina las ubicaciones de todos los cuerpos físicos en la escena. Luego determina si ocurrieron colisiones o contactos. Este método computacional es rápido, pero a veces puede ocasionar colisiones perdidas. Un cuerpo pequeño puede moverse tan rápido que pasa completamente a través de otro cuerpo de física sin tener un cuadro de animación donde los dos se tocan.
Si tiene cuerpos de física que deben colisionar, puede indicarle a Sprite Kit que use un modelo de colisión más preciso para verificar las interacciones. Este modelo es más caro, por lo que debe usarse con moderación. Cuando cualquiera de los cuerpos utiliza colisiones precisas, se contactan y prueban varias posiciones de movimiento para garantizar que se detecten todos los contactos.
ship.physicsBody.usesPreciseCollisionDetection = YES;
Otras posibilidades también pueden arruinar las colisiones, como la información de posición incorrecta para la ruta que está asignando al cuerpo de física. Es importante comprender que cuando establece una ruta a un nodo, esa forma se establece usando el sistema de coordenadas local del nodo. Es importante recordar que el origen del Kit Sprite se encuentra en la esquina inferior izquierda (no en la esquina superior izquierda de UIKit) y cuando asigna una ruta a un cuerpo físico de un nodo, la ruta se coloca en relación con el punto de anclaje del nodo .
Por ejemplo:
SKShapeNode *ball = [[SKShapeNode alloc] init];
CGRect ballFrame = CGRectMake(-25.0, -25.0, 50.0, 50.0);
[ball setPath:[UIBezierPath bezierPathWithOvalInRect:ballFrame].CGPath];
[ball setPosition:CGPointMake(100.0, 450.0)];
[ball setFillColor:[UIColor redColor]];
[ball setPhysicsBody:[SKPhysicsBody bodyWithCircleOfRadius:25.0]];
Si hubiera establecido el origen de "ballFrame" en (0,0), entonces el círculo del cuerpo de física con un radio de 25.0 no coincidiría con la forma de la bola, ya que la esquina inferior izquierda del cuerpo de física será colocado en el punto de anclaje de la pelota, que está en los puntos x = 0 ey = 0, en el sistema de coordenadas local de la pelota.