/ / Connect Physicsbodies sur TileMap dans SpriteKit - swift, sprite-kit, skphysicsbody, sktilemapnode

Connectez des corps physiques sur TileMap dans SpriteKit - swift, sprite-kit, skphysicsbody, sktilemapnode

J'utilise la fonction suivante pour ajouter des corps physiques sur des tuiles à partir d'un SKTileMapNode:

 static func addPhysicsBody(to tileMap: SKTileMapNode, and tileInfo: String){

let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2 * tileSize.height

for row in 0..<tileMap.numberOfColumns{
for column in 0..<tileMap.numberOfRows{
let tileDefinition = tileMap.tileDefinition(atColumn: column, row: row)
let isCorrectTile = tileDefinition?.userData?[tileInfo] as? Bool
if isCorrectTile ?? false && tileInfo == "wall"{

let x = CGFloat(column) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight

let tileNode = SKNode()
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2, y: tileSize.height / 2))
tileNode.physicsBody!.isDynamic = false
tileNode.physicsBody!.restitution = 0.0
tileNode.physicsBody!.categoryBitMask = Constants.PhysicsCategories.wall
tileNode.physicsBody!.collisionBitMask = Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc | Constants.PhysicsCategories.enemy
nodesForGraph.append(tileNode)
tileMap.addChild(tileNode)
}
}
}
}

Cependant, si j'utilise ceci, j'ai un corps physique par tuile. Je veux connecter des corps physiques à des corps plus grands pour obtenir de meilleures performances. Je sais que ça peut être avec init(bodies: [SKPhysicsBody]). Mais comment faire ça?
Comment puis-je savoir quel corps est à côté d'un autre corps pour les regrouper?
Les corps physiques dans le tileMap ne sont pas tous les suivantsles uns aux autres. Certains sont de gros blocs de corps physiques, certains sont des corps physiques uniques sans corps à côté d'eux. Je ne peux donc pas simplement mettre chaque corps physique dans un tableau et les regrouper.
Voici une image qui montre à quoi elle ressemble en ce moment.

TileMap Physics

J'espère que l'explication est suffisamment claire. Sinon, je vais essayer de mieux l'expliquer.

Quelqu'un a-t-il déjà fait cela et peut-il m'orienter dans la bonne direction? J'apprécierais toute aide.

ÉDITER: Avant d'essayer ceci:

static var bodies = [SKPhysicsBody]()
static func addPhysicsBody(to tileMap: SKTileMapNode, and tileInfo: String){

let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2 * tileSize.height

for column in 0..<tileMap.numberOfColumns{
for row in 0..<tileMap.numberOfRows{
let tileDefinition = tileMap.tileDefinition(atColumn: column, row: row)
let isCorrectTile = tileDefinition?.userData?[tileInfo] as? Bool
if isCorrectTile ?? false && tileInfo == "wall"{

let x = CGFloat(column) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight

let tileNode = SKNode()
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2, y: tileSize.height / 2))
tileNode.physicsBody!.isDynamic = false
tileNode.physicsBody!.restitution = 0.0
tileNode.physicsBody!.categoryBitMask = Constants.PhysicsCategories.wall
tileNode.physicsBody!.collisionBitMask = Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc | Constants.PhysicsCategories.enemy
//nodesForGraph.append(tileNode)
bodies.append(tileNode.physicsBody!)
tileMap.addChild(tileNode)
}
}
}
tileMap.physicsBody = SKPhysicsBody(bodies: bodies)
}

Mais quand je fais ça, les corps physiques sont totalement foirés ..

Réponses:

0 pour la réponse № 1

Comme l'a souligné Knight0fDragon, il n'y a aucun moyen defaites exactement ce que vous avez demandé. Malheureusement, les cartes de tuiles dans SpriteKit laissent beaucoup à désirer. Mais vous pourriez essayer cette technique pour réduire le nombre de corps physiques.

Idée n ° 1 - Dessinez manuellement vos corps physiques

Créez votre carte de tuiles dans l'éditeur. Peignez simplement vos textures de tuile sur la carte; ne leur attribuez aucun corps physique. Continuez à travailler dans l'éditeur pour faire glisser Color Sprites (SKSpriteNodes) sur des parties de votre carte qui nécessitent un corps physique. Formez les nœuds pour créer le plus grand rectangle possible pour les zones qui nécessitent des corps physiques. Cela fonctionne mieux pour les grandes surfaces planes comme les murs, les planchers, les plafonds, les plates-formes, les caisses, etc. Faire.

Idée n ° 2 - N'utiliser aucun corps physique

Cette idée nécessiterait probablement encore plus de travail,mais vous pourriez potentiellement éviter complètement d'utiliser des corps physiques. Tout d'abord, créez votre carte de tuiles dans l'éditeur. Analysez votre carte pour identifier quelles tuiles marquent une barrière, au-delà de laquelle le joueur ne doit pas traverser. Attribuez un identifiant de données utilisateur à ce type de mosaïque. Vous auriez besoin de différentes catégories d'identifiants pour différents types de barrières, et vous devrez peut-être également concevoir votre œuvre d'art pour l'adapter à cette approche.

Une fois que vos tuiles barrières sont suffisammentidentifié, écrivez un code qui vérifie la valeur des données utilisateur pour la tuile actuellement occupée par l'image-objet du joueur et restreignez le mouvement de l'image-objet en conséquence. Par exemple, si le joueur entre un titre qui marque une limite supérieure, votre code de mouvement ne permettrait pas De même, si le joueur entre dans une tuile qui marque la limite la plus à gauche, votre code de mouvement ne permettra pas au joueur de voyager à gauche.

Vous pouvez vérifier ce post connexe où je propose essentiellement les mêmes idées. Malheureusement, les cartes de tuiles de SpriteKit n'ont pas de solution parfaite à ce problème.