2015-12-29 2 views
0

Je souhaite reproduire Super Mario pour iOS en utilisant Swift et SpriteKit. J'utilise SKPhysics-bodies pour simuler des collisions entre le joueur et l'environnement. Le joueur et tous les objets ont leur propre SKPhysicsBody (rectangle de leur taille). Mais quand le joueur saute contre une brique (en haut à gauche ou en haut à droite) like this, le joueur se bloque dans les airs. Mon hypothèse est que lorsque les deux SKSpriteNodes entrent en collision, ils se chevauchent un tout petit peu. Et le SKPhysics-Engine pense que le joueur est au sommet de la brique du milieu parce que le joueur est un tout petit peu à l'intérieur de la brique et tombe sur la brique du milieu. Donc, ma question est: Comment puis-je empêcher SKSPriteNodes de se chevaucher? Ou comment puis-je résoudre ce problème?Empêche le chevauchement de deux SKSpriteNodes

P.S. Si vous avez besoin de plus d'informations pour répondre, s'il vous plaît dites-moi!

EDIT: Certains Code de la classe Brick:

import SpriteKit 

class Brick: SKSpriteNode { 

    let imgBrick = SKTexture(imageNamed: "Brick") 

    init(let xCoor: Float, let yCoor: Float) { 
     // position is a global variable wich is 1334/3840 
     super.init(texture: imgBrick, color: UIColor.clearColor(), size: CGSize(width: 80*proportion, height: 80*proportion)) 
     position = CGPoint(x:Int(xCoor*667)+Int(40*proportion), y:Int(375-(yCoor*375))-Int(40*proportion)) 
     name = "Brick" 
     physicsBody = SKPhysicsBody(rectangleOfSize: self.size) 
     physicsBody?.affectedByGravity = false 
     physicsBody?.dynamic = false 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

et ma classe Joueur

import SpriteKit 

class Mario: SKSpriteNode { 

    let atlas = SKTextureAtlas(named: "Mario") 
    var imgMario = [SKTexture]() 
    var action = SKAction() 

    init(let xCoor: Float, let yCoor: Float) { 
     for(var i = 1; i < 24; i++) { 
      imgMario.append(atlas.textureNamed("X\(i)")) 
     } 

     super.init(texture: imgMario[0], color: UIColor.clearColor(), size: CGSize(width: 120*proportion, height: 160*proportion)) 
     position = CGPoint(x:Int(xCoor)+Int(60*proportion), y:Int(yCoor)-Int(90*proportion)) 
     name = "Mario" 
     physicsBody = SKPhysicsBody(rectangleOfSize: self.size) 
     physicsBody?.allowsRotation = false 

     action = SKAction.repeatActionForever(SKAction.animateWithTextures(imgMario, timePerFrame: 0.03, resize: false, restore: true)) 
     runAction(action, withKey: "walking") 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

et une partie de mon niveau de classe

class Level: SKScene, SKPhysicsContactDelegate { 

    var motionManager = CMMotionManager() 

    var mario = Mario(xCoor: 100, yCoor: 90) 
    var world = SKSpriteNode() 

    let MarioCategory: UInt32 = 0x1 << 0 
    let BrickCategory: UInt32 = 0x1 << 1 

    /* 
    Some more code... 
    */ 

    func setUpPhysics() { 
     physicsWorld.contactDelegate = self 
     mario.physicsBody!.categoryBitMask = marioCategory 
     mario.physicsBody?.collisionBitMask = brickCategory 
     mario.physicsBody?.contactTestBitMask = brickCategory 

     for(var i = 0; i < world.children.count; i++) { 
      if(world.children[i].name == "Brick") { 
       world.children[i].physicsBody?.categoryBitMask = brickCategory 
       world.children[i].physicsBody?.collisionBitMask = marioCategory 
       world.children[i].physicsBody?.contactTestBitMask = marioCategory 
       world.children[i].physicsBody?.friction = 0 
      } 
     } 
    } 
} 
+0

sont les briques toutes les tuiles .. sont-ils des corps de physique multiples ou un grand corps de physique? – hamobi

+0

Vérifiez si les corps physiques sont disposés comme ils sont censés, si vous ne savez pas comment le faire, lisez [cette réponse] (http://stackoverflow.com/a/21295318/3462308). Si les corps sont corrects, essayez de placer 'block.physicsBody! .friction = 0' dans les blocs – alaphao

+0

Veuillez fournir le code afin que le problème puisse être correctement évalué. –

Répondre

0

Essayez réglage UsePreciseCollisionDetection true sur votre corps physique.

mario.physicsBody?.usesPreciseCollisionDetection = true

https://developer.apple.com/reference/spritekit/skphysicsbody a quelques exemples. En affectant la valeur true à cette propriété, vous pouvez détecter les collisions de manière plus précise, uniquement lorsque vous le souhaitez. Je repense également en donnant à chaque bloc son propre corps physique. Vous vous souciez uniquement du bord d'un groupe de blocs plutôt que des bords de chaque bloc.

Une autre suggestion est que vous pouvez créer un corps physique basé sur une texture. Donc, si votre SKSpriteNode a une texture complexe avec des bits transparents, vous pouvez créer une autre texture qui n'est qu'un simple bloc noir ou similaire, ce qui aidera le moteur à détecter des collisions plus précises.