Sprite Kit 中的单向平台碰撞 [英] One-way platform collisions in Sprite Kit

查看:20
本文介绍了Sprite Kit 中的单向平台碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Swift 制作 Doodle Jump 克隆游戏,但问题是当玩家跳跃时,它的头部会撞到平台底部而无法通过.我怎样才能让玩家越过平台并跳过它们?我的代码在这里:

I am making a Doodle Jump clone game in Swift and the issue is that when the player jumps, it hits its head on the bottom of the platform and doesn't pass through. How can I make the player pass over the platform and jump through them? I have my code here:

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    var hero = SKSpriteNode(imageNamed: "hero");
    var stepSizeTest = SKSpriteNode(imageNamed: "step");
    var start = false;
    var jumpSpeed = CGFloat(0);
    var gravity = CGFloat(0);
    var stepPositionDivision:CGFloat = 0 //allows the step to spawn on specific places on y axes
    var setpPositionHeightIncrease:CGFloat = 0;

    var positionX:CGFloat = 0;
    var timeInterval:NSTimeInterval = 0;
    var CurTime:NSTimeInterval = 0;
    var TimeWhenThePreviousStepSpawned:NSTimeInterval = 0;
    var standart:Bool = false;
    var move:Bool = false;
    var oneJumpOnly:Bool = false;
    var cracked:Bool = false;
    var jumped:Bool = false;

    struct PhysicsCategory{
        static var None: UInt32 = 0;
        static var step: UInt32 = 0b1;
        static var hero: UInt32 = 0b10;
        static var All: UInt32 = UInt32.max;
    }

    func didBeginContact(contact: SKPhysicsContact) {
        var contactBody1: SKPhysicsBody;
        var contactBody2: SKPhysicsBody;
        if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask){
            contactBody1 = contact.bodyA;
            contactBody2 = contact.bodyB;
        }
        else{
            contactBody1 = contact.bodyB;
            contactBody2 = contact.bodyA;
        }

        if (contactBody1.categoryBitMask == PhysicsCategory.step && contactBody2.categoryBitMask == PhysicsCategory.hero){
            jumpSpeed = CGFloat(self.frame.size.height*0.01320422535);

        }
//        if (contactBody1.categoryBitMask == PhysicsCategory.ground && contactBody2.categoryBitMask == PhysicsCategory.hero){
//
//        }
    }

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        stepPositionDivision = self.frame.size.height/23;

        jumpSpeed = CGFloat(self.frame.size.height*0.01320422535);
        gravity = CGFloat(self.frame.size.height*(-0.0003521126761));

        self.physicsWorld.contactDelegate = self;

        self.physicsWorld.gravity = CGVectorMake(0,0);

        let sceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame);
        sceneBody.friction = 0;
        self.physicsBody = sceneBody;


        self.hero.anchorPoint = CGPoint(x: 0.5, y: 0.5);
        self.hero.position = CGPoint(x:self.frame.size.width/2, y:self.hero.size.height/2);
        self.hero.physicsBody = SKPhysicsBody(rectangleOfSize: self.hero.size)
        self.hero.physicsBody?.restitution = 1;
        self.hero.physicsBody?.affectedByGravity = false;
        self.hero.physicsBody?.friction = 0;
        self.hero.physicsBody?.categoryBitMask = PhysicsCategory.hero;
        self.hero.physicsBody?.collisionBitMask = PhysicsCategory.step;
        self.hero.physicsBody?.contactTestBitMask = PhysicsCategory.step;

        self.addChild(self.hero);
    }

    func ranPositionX() -> CGFloat{
        let stepSise = UInt32(self.stepSizeTest.size.width)
        let posX = arc4random_uniform(UInt32(self.frame.size.width) - stepSise) + stepSise
        return CGFloat(posX)
    }

    func stepSpawn(){
        if (setpPositionHeightIncrease < self.frame.size.height){
            let step = SKSpriteNode(imageNamed: "step");
            let posX = ranPositionX()

            step.anchorPoint = CGPoint(x: 0.5, y: 0.5);
            step.position = CGPoint(x:posX, y:setpPositionHeightIncrease);
            step.physicsBody = SKPhysicsBody(rectangleOfSize: step.size);
            step.physicsBody?.affectedByGravity = false;
            step.physicsBody?.dynamic = true;
            step.physicsBody?.friction = 0;
            step.physicsBody?.categoryBitMask = PhysicsCategory.step;
            step.physicsBody?.collisionBitMask = PhysicsCategory.None;
            step.physicsBody?.contactTestBitMask = PhysicsCategory.hero;

            self.addChild(step);
            setpPositionHeightIncrease += stepPositionDivision
        }
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
       /* Called when a touch begins */
        for touch in touches {

        }
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */

        self.hero.position.y += jumpSpeed
        jumpSpeed += gravity

        if (start == false){
            //self.hero.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 40))
            start = true;
        }
        stepSpawn()
    }
}

推荐答案

一种方法是在英雄跌倒或跳跃时打开/关闭适当的碰撞位.如果速度的 dy 属性小于零,则英雄正在下落,如果 dy 大于零,则英雄会跳跃(或弹起).以下是如何执行此操作的示例:

One way to do this is to toggle the appropriate collision bit(s) on/off, if the hero is falling or jumping. The hero is falling if its velocity's dy property is less than zero and jumping (or bouncing up) if dy is greater than zero. Here's an example of how to do this:

// Add this to the update method
if let body = hero.physicsBody {
    let dy = body.velocity.dy
    if dy > 0 {
        // Prevent collisions if the hero is jumping
        body.collisionBitMask &= ~PhysicsCategory.step
    }
    else {
        // Allow collisions if the hero is falling
        body.collisionBitMask |= PhysicsCategory.step
    }
}

这篇关于Sprite Kit 中的单向平台碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆