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