Swift GameKit在Arc中移动精灵

时间:2018-01-15 19:05:31

标签: ios swift sprite-kit gamekit

我需要一些帮助才能让玩家在我的平台游戏中跳跃。我遇到的问题是他跳过了他不应该做的支柱(我的物理设置正确)。我怀疑这是因为我的代码非常低效。我知道有更好的方法可以让他走上一条路,但我不知道该怎么做。

var xStep = CGFloat(18)
var yStep = CGFloat(30)

var x = CGFloat(playerJump.position.x)
var y = CGFloat(playerJump.position.y)

let follow = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y += yStep
let follow2 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y += yStep
let follow3 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y += yStep
let follow4 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y += yStep
let follow5 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y -= yStep
let follow6 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y -= yStep
let follow7 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y -= yStep
let follow8 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)
x += xStep
y -= yStep
let follow9 = SKAction.move(to: CGPoint(x: x, y:y), duration: 0.1)

let group = SKAction.group([
    SKAction.repeat(jumpAnimation!, count: 1),
           SKAction.sequence([follow,follow2,follow3,follow4,follow5,follow6,follow7,follow8,follow9])
])
if playerJump.parent == nil {
    addChild(playerJump)
}
playerJump.run(SKAction.sequence([group]), completion: {
    self.player.position=self.playerJump.position
    self.playerJump.removeAllActions()
    self.playerJump.removeFromParent()
    self.addChild(self.player)
})

提前感谢您的任何帮助。

更新 当我增加xStep中的值时,问题就开始了。角色跳跃的总距离会使它越过支柱。这就是我认为我的代码存在问题的原因。这是一个关于发生了什么的视频。 Jumping Video

更新2 这是我最新的代码,它仍然将玩家放在支柱的另一边。

@objc func jumpTapped() {
    var xStep = CGFloat(18)
    let yStep = CGFloat(12)

    jumping=true
    xStep = player.xScale * xStep
    var x = player.position.x
    var y = player.position.y


    var moveAnimation = [SKAction]()

    for i in 0...8 {
        x += xStep
        if i < 5 {
            y += yStep
        } else {
            y -= yStep
        }
        let move = SKAction.move(to: CGPoint(x: x, y: y), duration: 0.1)
        moveAnimation.append(move)
    }

    let group = SKAction.group([jumpAnimation!, SKAction.sequence(moveAnimation)])

    player.physicsBody?.affectedByGravity = false
    player.removeAllActions()
    player.run(group) {
        self.endJump()
    }
}

func endJump() {
    player.removeAllActions()
    player.physicsBody?.affectedByGravity = true
    player.run(SKAction.repeatForever(self.playerAnimation!))
    jumping=false
}

2 个答案:

答案 0 :(得分:1)

看起来你正在将player.position设置为self.playerJump.position

这可能是你的问题,它超越了支柱的位置。你可能也说过player.position.x = player.position.x + 500,它会把你放在支柱的另一边,同时忽略任何物理。

为什么要添加精灵并在其上运行操​​作?为什么不直接在播放器精灵上运行动画和动作?

就清理代码而言,你可以试试这个。还有其他一些你可以做的事情,比如让角色沿着Bezier路径跳跃,但这可能对你正在做的事情很好。但我非常怀疑这会对你跳过支柱的球员问题产生任何影响。

一些小花絮。

精灵位置已经是CGFloat,无需投射它们

短手完成代码语法为object.run(someAction) { //do something when complete }

运行重复1的动作是没有意义的

运行单个动作(SKAction.sequence([group]))的序列也是没有意义的

var xStep = CGFloat(18)
var yStep = CGFloat(30)

var x = playerJump.position.x
var y = playerJump.position.y
var moveAnimation: [SKAction]!

for _ in 0...9 {
    x += xStep
    y += yStep
    moveAnimation.append(SKAction.move(to: CGPoint(x: x, y: y), duration: 0.1))
}

let group = SKAction.group([jumpAnimation, SKAction.sequence(moveAnimation)])

guard playerJump.parent else { addChild(playerJump)}

playerJump.run(group) {
    self.player.position = self.playerJump.position
    self.playerJump.removeAllActions()
    self.playerJump.removeFromParent()
    self.addChild(self.player)
}
  

编辑尝试将以下功能添加到您的代码

func didBegin(_ contact: SKPhysicsContact) {

    let contactAName = contact.bodyA.node?.name
    let contactBName = contact.bodyB.node?.name

    if (contactAName == "pillar") || (contactBName == "pillar") {
        //assuming only player can hit pillar so don't need to check if one of the contacts is player
        endJump()
    }
}

答案 1 :(得分:0)

我弄清楚我做错了什么。我的错误是在SKAction中移动精灵。我应该在更新方法中移动精灵。所以,我把它添加到update():

    if jumping {
            if jumpCount > 3 {
                player.position.x += xStep // Jump straight up for a couple of frames to clear steps
            }
            if jumpCount < maxJump/2 {
                player.position.y += yStep  //Move sprite up for first half of jump
            } else {
                player.position.y -= yStep //Move sprite down for last half of jump
            }
            jumpCount += 1
            if jumpCount >= maxJump {
                endJump()
            }
        }

所有碰撞检测都能正常工作,玩家不会跳过支柱。