我想在Y轴上移动一个SKSpriteNode.名为Player的SKSpriteNode没有VeLocity.如果Platform与之联系,则播放器只能跳转.

每当屏幕被触动时,我想给玩家一个冲动,最小的冲动或最大的冲动

如果屏幕被轻拍,则最小脉冲应该是例如. y = 50.
如果屏幕保持,则表示手指长度在屏幕上,最大值应为例如. y = 100.

但是玩家也应该能够在最小和最大高度之间跳跃,屏幕不长,但也不短短,玩家只能得到y = 70的冲动.

如果屏幕保持,播放器应该跳到最大高度,掉下来,如果它再次与平台接触,则应该跳转,因为您仍然按住屏幕.

我已经尝试了这个线程中的建议答案:StackOverFlow
但这并不是最小的跳跃,也没有按下跳.

为了清楚起见:脉冲不应该在水龙头完成之后,而是在轻敲.你持有的时间越长,跳跃越长.

import SpriteKit
import GameKit

struct Constants {

static let minimumJumpForce:CGFloat = 40.0
static let maximumJumpForce:CGFloat = 60.0
static let characterSideSpeed:CGFloat = 18.0
}

class GameScene: SKScene,SKPhysicsContactDelegate {

var Player: SKSpriteNode!

var Platform0: SKSpriteNode!

var World: SKNode!
var Camera: SKNode!

var force: CGFloat = 40.0

var pressed = false

var isCharacterOnGround = false

.....

func SpawnPlatforms() {

Platform0 = SKSpriteNode (color: SKColor.greenColor(),size: CGSize(width: self.frame.size.width,height: 25))
Platform0.position = CGPoint(x: self.frame.size.width / 2,y: -36)
Platform0.zPosition = 1

Platform0.physicsBody = SKPhysicsBody(rectangleOfSize:Platform0.size)
Platform0.physicsBody?.dynamic = false
Platform0.physicsBody?.allowsRotation = false
Platform0.physicsBody?.restitution = 0
Platform0.physicsBody?.usesPreciseCollisionDetection = true

Platform0.physicsBody?.categoryBitMask = Platform0Category
Platform0.physicsBody?.collisionBitMask = PlayerCategory
Platform0.physicsBody?.contactTestBitMask = PlayerCategory

World.addChild(Platform0)

}

func SpawnPlayer(){

Player = SKSpriteNode (imageNamed: "Image.png")
Player.size = CGSize(width: 64,height: 64)
Player.position = CGPoint(x: self.frame.size.width / 2,y: 0)
Player.zPosition = 2

Player.physicsBody = SKPhysicsBody(rectangleOfSize:CGSize(width: 35,height: 50))
Player.physicsBody?.dynamic = true
Player.physicsBody?.allowsRotation = false
Player.physicsBody?.restitution = 0.1
Player.physicsBody?.usesPreciseCollisionDetection = true

Player.physicsBody?.categoryBitMask = PlayerCategory
Player.physicsBody?.collisionBitMask = Platform0Category
Player.physicsBody?.contactTestBitMask = Platform0Category | Platform1Category | Platform2Category | Platform3Category | Platform4Category | Platform5Category

World.addChild(Player)

}

func jump(force : CGFloat){


    if(self.isCharacterOnGround){

        self.Player.physicsBody?.applyImpulse(CGVectorMake(0,force))
        self.isCharacterOnGround = false
    }

}

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

    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)

        self.pressed = true

        let timerAction = SKAction.waitForDuration(0.0)

        let update = SKAction.runBlock({
            if(self.force < Constants.maximumJumpForce){
                self.force += 2.0
            }else{
                self.jump(Constants.maximumJumpForce)
                self.force = Constants.maximumJumpForce
            }
        })
        let sequence = SKAction.sequence([timerAction,update])
        let repeat = SKAction.repeatActionForever(sequence)
        self.runAction(repeat,withKey:"repeatAction")
    }
}

override func touchesEnded(touches: Set<NSObject>,withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)

        self.removeActionForKey("repeatAction")

        self.jump(self.force)

        self.force = Constants.minimumJumpForce

        self.pressed = false

}
}

func didBeginContact(contact: SKPhysicsContact) {

    //this gets called automatically when two objects begin contact with each other

    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    switch(contactMask) {

    case PlayerCategory | Platform0Category:
        //either the contactMask was the bro type or the ground type
        println("Contact Made0")
        Green = true
        self.isCharacterOnGround = true

    default:
        return

    }

}

解决方法

这是一个关于如何制作如下的工作示例:

>按压时间长按压跳跃
>短(一击)
>限制人物在空中跳跃
>手指在屏幕上保持字符跳跃

import SpriteKit

    struct Constants {

        static let minimumJumpForce:CGFloat = 15.0
        static let maximumJumpForce:CGFloat = 30.0
        static let characterSideSpeed:CGFloat = 18.0
    }

    class GameScene: SKScene,SKPhysicsContactDelegate
    {
        let CharacterCategory   : UInt32 = 0x1 << 1
        let PlatformCategory    : UInt32 = 0x1 << 2
        let WallCategory        : UInt32 = 0x1 << 3

        var force: CGFloat = 16.0 //Initial force

        var pressed = false

        var isCharacterOnGround = false // Use this to prevent jumping while in the air

        let character = SKSpriteNode(color: SKColor.greenColor(),size: CGSize(width: 30,height:30))


        let   debugLabel = SKLabelNode(fontNamed: "Geneva")

        override func didMovetoView(view: SKView)
        {
            //Setup contact delegate so we can use didBeginContact and didEndContact methods
            physicsWorld.contactDelegate = self
            physicsWorld.speed = 0.5
            //Setup borders so character can't escape from us :-)
            self.physicsBody = SKPhysicsBody(edgeLoopFromrect: self.frame)
            self.physicsBody?.categoryBitMask = WallCategory
            self.physicsBody?.collisionBitMask = CharacterCategory


            //Setup character
            character.position = CGPoint(x: 150,y: 150)
            character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
            character.physicsBody?.categoryBitMask = CharacterCategory
            character.physicsBody?.contactTestBitMask = PlatformCategory
            character.physicsBody?.collisionBitMask = PlatformCategory | WallCategory
            character.physicsBody?.allowsRotation = false
            character.physicsBody?.dynamic = true
            character.physicsBody?.restitution = 0.1

            self.addChild(character)

            generatePlatforms()

            debugLabel.text = " DEBUG: "
            debugLabel.fontColor = SKColor.whiteColor()
            debugLabel.fontSize = 12.0
            debugLabel.position = CGPoint(x: CGRectGetMidX(frame),y: CGRectGetMidY(frame)+100)
            self.addChild(debugLabel)


        }

        func generatePlatforms(){


            for i in 1...4
            {



                let position = CGPoint(x: CGRectGetMidX(frame),y: CGFloat(i)*140.0 - 100)

                let platform = createPlatformAtPosition(position)

                self.addChild(platform)

            }


        }


        func createPlatformAtPosition(position : CGPoint)->SKSpriteNode{

            let platform = SKSpriteNode(color: SKColor.greenColor(),size: CGSize(width:frame.size.width,height:20))

            platform.position = position

            platform.physicsBody = SKPhysicsBody(
                edgeFromPoint: CGPoint(x: -platform.size.width/2.0,y:platform.size.height/2.0),toPoint:CGPoint(x: platform.size.width/2.0,y: platform.size.height/2.0))

            platform.physicsBody?.categoryBitMask       = PlatformCategory
            platform.physicsBody?.contactTestBitMask    = CharacterCategory
            platform.physicsBody?.collisionBitMask      = CharacterCategory
            platform.physicsBody?.allowsRotation        = false
            platform.name = "platform"
            platform.physicsBody?.dynamic               = false
            platform.physicsBody?.restitution = 0.0

            return platform
        }

        func jump(force : CGFloat){


            if(self.isCharacterOnGround){

                self.character.physicsBody?.applyImpulse(CGVectorMake(0,force))
                self.character.physicsBody?.collisionBitMask = WallCategory
                self.isCharacterOnGround = false
            }

        }

        override func touchesBegan(touches: NSSet,withEvent event: UIEvent) {

            self.pressed = true

            let timerAction = SKAction.waitForDuration(0.05)

            let update = SKAction.runBlock({
                if(self.force < Constants.maximumJumpForce){
                    self.force += 2.0
                }else{



                  self.jump(Constants.maximumJumpForce)

                  self.force = Constants.maximumJumpForce


                }
            })
            let sequence = SKAction.sequence([timerAction,update])
            let repeat = SKAction.repeatActionForever(sequence)
            self.runAction(repeat,withKey:"repeatAction")

        }


        override func touchesEnded(touches: NSSet,withEvent event: UIEvent) {

            self.removeActionForKey("repeatAction")

            self.jump(self.force)

            self.force = Constants.minimumJumpForce

            self.pressed = false
        }


        override func update(currentTime: NSTimeInterval) {


            debugLabel.text = "DEBUG: onTheGround : \(isCharacterOnGround),force \(force)"



            if(character.position.x <= character.size.width/2.0 + 5.0 && character.physicsBody?.veLocity.dx < 0.0 ){

               character.physicsBody?.applyForce(CGVectorMake(Constants.characterSideSpeed,0.0))


            }else if((character.position.x >= self.frame.size.width - character.size.width/2.0 - 5.0) && character.physicsBody?.veLocity.dx >= 0.0){

                character.physicsBody?.applyForce(CGVectorMake(-Constants.characterSideSpeed,0.0))

            }else if(character.physicsBody?.veLocity.dx > 0.0){

               character.physicsBody?.applyForce(CGVectorMake(Constants.characterSideSpeed,0.0))

            }else{

                character.physicsBody?.applyForce(CGVectorMake(-Constants.characterSideSpeed,0.0))

            }


        }


    func didBeginContact(contact: SKPhysicsContact) {

        var firstBody,secondBody: SKPhysicsBody

        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }


        if ((firstBody.categoryBitMask & CharacterCategory) != 0 &&
            (secondBody.categoryBitMask & PlatformCategory != 0)) {

            let platform = secondBody.node as SKSpriteNode
            //  platform.color = UIColor.redColor()
            let platformSurfaceYPos = platform.position.y + platform.size.height/2.0

            let player = contact.bodyB.node as SKSpriteNode
            let playerLegsYPos = player.position.y - player.size.height/2.0



            if((platformSurfaceYPos <= playerLegsYPos)  ){

                character.physicsBody?.collisionBitMask = PlatformCategory | WallCategory



                self.isCharacterOnGround = true

                if(self.pressed){


                    var characterDx = character.physicsBody?.veLocity.dx

                    character.physicsBody?.veLocity = CGVector(dx: characterDx!,dy: 0.0)

                    self.jump(Constants.maximumJumpForce)
                }

            }


        }



    }

    func didEndContact(contact: SKPhysicsContact) {

        var firstBody,secondBody: SKPhysicsBody

        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }

        if ((firstBody.categoryBitMask & CharacterCategory) != 0 &&
            (secondBody.categoryBitMask & PlatformCategory != 0)) {


            let platform = secondBody.node as SKSpriteNode
            let platformSurfaceYPos = platform.position.y + platform.size.height/2.0

            let player = contact.bodyB.node as SKSpriteNode
            let playerLegsYPos = player.position.y - player.size.height/2.0



            if((platformSurfaceYPos <= playerLegsYPos) && (character.physicsBody?.veLocity.dy > 0.0)){

                character.physicsBody?.collisionBitMask = WallCategory

                self.isCharacterOnGround = false

            }

        }

    }

}

请注意,这是一个简单的例子,在实际应用中,您可能需要以不同的方式处理像isOnTheGround这样的状态.现在,要确定字符是否在地面上,您只需设置isOnTheGround = true,当字符与平台进行联系时,在didEndContact中设置为false …但是有些情况下,当与空气(如侧面接触)…

编辑:

我改变了代码,让玩家在按下时跳跃.结果如下:

重要:

实际的平台实施和联系人处理取决于你,这并没有被测试.此示例的唯一目的是向您展示如何在按下时跳转.目前,physicsWorld.speed设置为0.5,使动画更慢,因为它更容易调试,但可以将其更改为默认值(1.0).

所以,从图像可以看出,当玩家在第一个平台上时,会出现一些小跳跃(通过简单的敲击或短按).然后(玩家还在第一个平台上)长按了,玩家已经跳上了第二个平台.之后,又做了一个长时间的新闻,但这次没有释放,玩家开始从一个平台跳到另一个平台,最大的力量.

这需要大量的调整和适当的平台&联系检测,但它可以给你一个想法如何实现跳跃你问.

ios – 雪碧套装套装和最大为跳的更多相关文章

  1. Swift开发Sprite Kit游戏实践三:物理推力与碰撞检测

    物理推力为了避免monkey“落下”,需要用物理推力让它重新跳起来。现在轮到为敌人的sprite添加physicsbody了,来制造碰撞效果。首先将如下所示添加至GameScene.swift最顶端:这里要做的就是为每个sprite创建类别。此处执行针对两个physicsbody相撞的method。physicsbody不一定要跟sprite的形状完全吻合,近似就好。这里用的是圆形,半径设为sprite的1/4,免得碰撞效果太猛。把dynamic关掉,实现物理控制sprite。防止引力对sprite的影响

  2. 用Swift做个游戏Lecture06 —— 碰撞的检测

    collisionBitMask告知能与哪些物体碰撞。确实,如果通过自己实时检测实在过于劳累,何不让SpriteKit来帮你代劳,每当物体之间发生碰撞了,立马通知你来处理事件。正处于游戏的状态。Player因为不小心碰到障碍物失败下落时刻。标识符,记录Player是否碰撞了仙人掌。好吧,请看lecture02中的时间间隔图,匆忙的你找找原因,试试解决吧。

  3. angularjs – 为什么在使用离子滚动时需要$parent来启用ng-click功能?

    我使用以下版本:>Ionic,v1.0.0-beta.14>AngularJSv1.3.6路线配置:控制器配置:查看配置:正如您在视图中看到的,我需要在以下字段中使用$parent来使其工作:>ng-model=“$parent.search_contact”>ng-repeat=“联系$parent.filteredContacts=(contactsToBeInvited|filter:sea

  4. angularjs – Angular TypeError:无法在字符串”上创建属性

    单击“添加”后尝试清除输入框,就像这个人在thistutorial中所做的那样.我使用这个简短的代码重新创建了错误,而没有使用API.您还可以查看Plunker.HTMLJS似乎我可以添加1项,但在第二个我得到此错误:您没有以正确的方式清理联系人对象.在Add()函数中,更改:至:ForkedPlunker

  5. angular2的组件传值Input和Output

    #parent-to-child

  6. ios – 雪碧套装套装和最大为跳

    但是有些情况下,当与空气…

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部