每当屏幕被触动时,我想给玩家一个冲动,最小的冲动或最大的冲动
如果屏幕被轻拍,则最小脉冲应该是例如. 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).
所以,从图像可以看出,当玩家在第一个平台上时,会出现一些小跳跃(通过简单的敲击或短按).然后(玩家还在第一个平台上)长按了,玩家已经跳上了第二个平台.之后,又做了一个长时间的新闻,但这次没有释放,玩家开始从一个平台跳到另一个平台,最大的力量.
这需要大量的调整和适当的平台&联系检测,但它可以给你一个想法如何实现跳跃你问.