我想在Y轴
上移动一个名为Player的SKSpriteNode。Player没有Velocity
,只有在与平台接触时才能跳跃。
每次屏幕被触摸时,我想给Player一个最小冲量或最大冲量的脉冲。
如果屏幕短暂被点击,则最小的冲量应为例如y = 50
。
如果屏幕被长按,则最大值应为例如y = 100
。
但是,如果屏幕不是长时间按下也不是短时间按下,玩家还可以跳跃到最小和最大高度之间,此时,Player应该只获得 y = 70
的冲量。
如果屏幕被长按住,则Player应该跳到他的最大高度,然后落下,并且如果它再次接触到平台,则应该跳跃,因为你仍然按住屏幕。
我已经尝试了这个问题,使用了这个线程中建议的答案: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
}
}