我需要一些帮助才能让玩家在我的平台游戏中跳跃。我遇到的问题是他跳过了他不应该做的支柱(我的物理设置正确)。我怀疑这是因为我的代码非常低效。我知道有更好的方法可以让他走上一条路,但我不知道该怎么做。
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
}
答案 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()
}
}
所有碰撞检测都能正常工作,玩家不会跳过支柱。