所以我尝试使用skphysicscontact但是当“cat”和“spinnynode”碰撞时,即使有物理交互,也没有来自它们的输出
另一方面,为什么定时器功能不起作用?它似乎根本没有召唤出这个功能。
请帮助,我是新手。感谢import SpriteKit
import GameplayKit
import UIKit
import Foundation
struct physicsCollision {
static let cat: UInt32 = 1
static let spinnyNode: UInt32 = 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var entities = [GKEntity]()
var graphs = [String : GKGraph]()
var catTimer = Timer()
var score = 0
private var lastUpdateTime : TimeInterval = 0
private var label : SKLabelNode?
private var spinnyNode : SKShapeNode?
let meow = SKAction.playSoundFileNamed("cat meow", waitForCompletion: false)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
//random range
func randomInRange(lo: Float, hi : Float) -> Float{
return lo + Float(arc4random_uniform(UInt32(hi - lo + 1)))
}
//spawn cat
func spawnCat(){
// x coordinate between MinX (left) and MaxX (right):
let randomX = randomInRange(lo: Float(self.frame.minX + 5), hi: Float(self.frame.maxX + 5))
let startPoint = CGPoint(x: CGFloat(randomX), y: self.frame.height * 1.2)
let endPoint = CGPoint(x: CGFloat(randomX), y:self.frame.height * -0.5)
let cat = SKSpriteNode(imageNamed: "before right")
cat.name = "cat"
cat.setScale(0.3)
cat.position = startPoint
cat.zPosition = 1
cat.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: cat.size.width, height: cat.size.height))
cat.physicsBody?.affectedByGravity = false
cat.physicsBody?.categoryBitMask = physicsCollision.cat
cat.physicsBody?.contactTestBitMask = physicsCollision.spinnyNode
cat.physicsBody?.collisionBitMask = physicsCollision.spinnyNode
cat.physicsBody?.isDynamic = false
self.addChild(cat)
let moveCat = SKAction.move(to: endPoint, duration: 5)
let deleteCat = SKAction.removeFromParent()
let catSequence = SKAction.sequence([moveCat, meow, deleteCat])
cat.run(catSequence)
}
//contact func
func didBeginContact(contact:SKPhysicsContact){
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
if contact.bodyA.node?.name == "cat"
{
firstBody = contact.bodyA
secondBody = contact.bodyB
}
else{
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.node?.name == "cat" && (secondBody.node?.name)! == "skinnynode"{
print("contacted")
}
}
override func sceneDidLoad() {
self.physicsWorld.contactDelegate = self
self.lastUpdateTime = 0
//spawn cat at intervals,, time interval to decrease when points increase, use if loop
catTimer = Timer.init(timeInterval: 1 , target: self, selector: Selector(("cat")), userInfo: nil, repeats: true)
// Create shape node to use during mouse interaction
let w = (self.size.width + self.size.height) * 0.05
self.spinnyNode = SKShapeNode.init(rectOf: CGSize.init(width: w, height: w), cornerRadius: w * 0.5)
spinnyNode?.name = "spinnynode"
spinnyNode?.physicsBody = SKPhysicsBody(circleOfRadius: 0.5)
spinnyNode?.physicsBody?.affectedByGravity = false
spinnyNode?.zPosition = 1
spinnyNode?.physicsBody?.categoryBitMask = physicsCollision.spinnyNode
if let spinnyNode = self.spinnyNode{
spinnyNode.lineWidth = 1.5
spinnyNode.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat(Double.pi), duration: 1)))
spinnyNode.run(SKAction.sequence([SKAction.wait(forDuration: 0.5),
SKAction.fadeOut(withDuration: 0.3),
SKAction.removeFromParent()]))
}
//create score label
let scoreLabel = UILabel(frame: CGRect(x:((self.frame.height) * 0.5) , y:((self.frame.width) * 0.3), width: (self.frame.size.width)/3, height: 30))
scoreLabel.center = CGPoint(x: (self.frame.size.width)/1.6 , y: (self.frame.size.height)/2)
scoreLabel.textColor = UIColor.white
scoreLabel.text = "\(score)"
self.view?.addSubview(scoreLabel)
}
func touchDown(atPoint pos : CGPoint) {
if let n = self.spinnyNode?.copy() as! SKShapeNode? {
n.position = pos
n.strokeColor = SKColor.green
self.addChild(n)
}
}
func touchMoved(toPoint pos : CGPoint) {
if let n = self.spinnyNode?.copy() as! SKShapeNode? {
n.position = pos
n.strokeColor = SKColor.purple
self.addChild(n)
}
}
func touchUp(atPoint pos : CGPoint) {
if let n = self.spinnyNode?.copy() as! SKShapeNode? {
n.position = pos
n.strokeColor = SKColor.red
self.addChild(n)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
spawnCat()
if let label = self.label {
label.run(SKAction.init(named: "Pulse")!, withKey: "fadeInOut")
}
for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
// Initialize _lastUpdateTime if it has not already been
if (self.lastUpdateTime == 0) {
self.lastUpdateTime = currentTime
}
// Calculate time since last update
let dt = currentTime - self.lastUpdateTime
// Update entities
for entity in self.entities {
entity.update(deltaTime: dt)
}
self.lastUpdateTime = currentTime
}
}
答案 0 :(得分:2)
你拼错了这个功能。永远不会被召唤。这是正确的协议功能名称:
func didBegin(_ contact: SKPhysicsContact) {
// Your stuff here..
}
您可以使用自动填充功能来避免此问题。开始输入&#34; didbegin&#34;你将让Xcode填写正确的函数:
暂且不说:
此外,您正在使用硬编码字符串,以后可能会导致问题。也许您可以尝试使用常量值或结构来避免字符串中可能出现的拼写错误:
let names = (cat: "cat", spinnynode: "spinnynode")
// cat.name = names.cat, etc...
func didBeginContact(contact:SKPhysicsContact){
// ...
if contact.bodyA.node?.name == names.cat
{
firstBody = contact.bodyA
secondBody = contact.bodyB
}
else{
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.node?.name == names.cat && secondBody.node!.name == names.spinnynode {
print("contacted")
}
}
答案 1 :(得分:0)
您是否尝试过使用SKPhysicsContactDelegate的categoryBitMask
方法?您可以通过进入GameScene.sks文件并将Category Mask
分配给默认值以外的数字来解决您的问题。为您的两个实体执行此操作,但为每个实体指定不同的值。
然后,在你的GameScene.swift中,你的didBegin
联系人函数可能如下所示:
class GameScene: SKScene, SKPhysicsContactDelegate {
//set these values to the same number in your GameScene.sks file
let catCategory = 2
let skinnyNodeCategory = 3
func didBegin(_ contact: SKPhysicsContact) {
let bodyA = contact.bodyA
let bodyB = contact.bodyB
//check to see if the bodies in contact match
//the category mask numbers you defined
//here the conditional is set to say that either of the bodies
//in contact match the categoryBitMask number set in the GameScene.sks file
//using && may not work depending on how the categoryBitMask identifiers
//are assigned by the physicsContactDelegate
if bodyA.categoryBitMask == catCategory || bodyB.categoryBitMask == catCategory {
print("contacted")
}
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}