在下面的代码中,'英雄'从关卡开始。当它在地图上移动时,地图外部的黑色区域变得可见。当英雄走到墙上他停下来。但是,如果我触摸水平线以外的黑色区域,英雄会跳过墙壁并进入水平区域外。此外,有时当英雄接触墙壁时,他会以相反的方向反弹。 (我并不确定是什么导致了这一点。)我想要做的就是将英雄保持在关卡中,并停止有时发生的反弹。
我不确定问题是否我没有正确地进行碰撞,或者我是否需要以某种方式阻止黑色区域完全可见。我认为停止展示级别之外的区域是我需要的,但是使用let scene = GameScene(size: view.bounds.size)
并将其更改为let scene = GameScene(size: tileMap.frame.size)
并不起作用。这是我的代码:
import SpriteKit
let tileMap = JSTileMap(named: "level2.tmx")
let hero = SKSpriteNode(imageNamed: "hero")
let theCamera: SKCameraNode = SKCameraNode()
class GameScene: SKScene, SKPhysicsContactDelegate {
enum ColliderType: UInt32 {
case Hero = 1
case Wall = 2
}
override func didMoveToView(view: SKView) {
self.physicsWorld.contactDelegate = self
self.anchorPoint = CGPoint(x: 0, y: 0)
self.position = CGPoint(x: 0, y: 0)
hero.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
hero.xScale = 0.5
hero.yScale = 0.5
hero.zPosition = 2
hero.physicsBody = SKPhysicsBody(circleOfRadius: hero.size.height / 2)
hero.physicsBody?.affectedByGravity = false
hero.physicsBody!.dynamic = true
hero.physicsBody!.categoryBitMask = ColliderType.Hero.rawValue
hero.physicsBody!.contactTestBitMask = ColliderType.Wall.rawValue
hero.physicsBody!.collisionBitMask = ColliderType.Wall.rawValue
tileMap.zPosition = 1
tileMap.position = CGPoint(x: 0, y: 0)
self.addChild(tileMap)
self.addChild(hero)
self.addChild(theCamera)
self.camera = theCamera
camera?.position = hero.position
addWalls()
}
func didBeginContact(contact: SKPhysicsContact) {
print("Hero made contact with a wall")
}
func addWalls() {
//Go through every point up the tile map
for var a = 0; a < Int(tileMap.mapSize.width); a++ {
//Go through every point across the tile map
for var b = 0; b < Int(tileMap.mapSize.height); b++ {
//Get the first layer (you may want to pick another layer if you don't want to use the first one on the tile map)
let layerInfo:TMXLayerInfo = tileMap.layers[1] as! TMXLayerInfo
//Create a point with a and b
let point = CGPoint(x: a, y: b)
//The gID is the ID of the tile. They start at 1 up the the amount of tiles in your tile set.
let gid = layerInfo.layer.tileGidAt(layerInfo.layer.pointForCoord(point))
//My gIDs for the floor were 2, 9 and 8 so I checked for those values
if gid == 1 {
//I fetched a node at that point created by JSTileMap
let node = layerInfo.layer.tileAtCoord(point)
//I added a physics body
node.physicsBody = SKPhysicsBody(rectangleOfSize: node.frame.size)
node.physicsBody?.dynamic = false
node.physicsBody!.categoryBitMask = ColliderType.Wall.rawValue
node.physicsBody!.contactTestBitMask = ColliderType.Hero.rawValue
node.physicsBody!.collisionBitMask = ColliderType.Wall.rawValue
}
}
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
let action = SKAction.moveTo(location, duration: 1)
hero.runAction(action)
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
let action = SKAction.moveTo(hero.position, duration: 0.25)
theCamera.runAction(action)
}
}
我的TMX文件:
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="24" height="42" tilewidth="32" tileheight="32" nextobjectid="13">
<tileset firstgid="1" name="grass-tiles-2-small" tilewidth="32" tileheight="32" tilecount="72">
<image source="grass-tiles-2-small.png" trans="ff00ff" width="384" height="192"/>
</tileset>
<layer name="Tile Layer 1" width="24" height="42">
<data encoding="base64" compression="zlib">
eJztzLEJAAAMw7Bs/f/jXhHIIINXJf2uNJ/P5/P5fD6fz+fz+Ut+swfI8xgR
</data>
</layer>
<layer name="Walls" width="24" height="42">
<data encoding="base64" compression="zlib">
eJztzLEJAAAMw7Dk/6d7RaCDDF7VJB2/is/n8/l8Pp/P5/P5/E/+8gMA/ACB
</data>
</layer>
</map>
以下是英雄接触墙壁时跳跃的视频以及跳过墙壁的Video of app sim
答案 0 :(得分:1)
当节点和物理体之间发生接触时,SpriteKit只会检测到接触,但在我们遇到日常生活中的障碍时,不会负责停止节点的动作。所以你需要手动停止它。
让我们为SKAction
hero
添加一个键值,以区分移动操作与将来可能添加的其他操作:
hero.runAction(action, withKey: "move")
然后,修改didBeginContact
方法以在发生联系时删除操作,我希望这会成为您想要的:
func didBeginContact(contact: SKPhysicsContact) {
print("Hero made contact with a wall")
// Stop your hero
hero.removeActionForKey("move")
}