我製作了一個遊戲,其基本思想是玩家精靈必須根據分配給敵人的字母與敵方精靈發生碰撞或避免掉落的敵方精靈。問題是,當我的玩家與一個精靈進行接觸時,周圍的敵人會大幅跳躍前進。這使得遊戲太難玩了,因爲沒有足夠的時間讓玩家擺脫即將來臨的敵方精靈。這發生在設備和模擬器上。SpriteKit敵方精靈在與玩家接觸後跳過
要看我的意思,看看這個簡短的視頻。 013:https://www.dropbox.com/s/8pp66baxc9uhy26/SimulatorScreenSnapz002.mov?dl=0
這裏是我的球員和敵人接觸代碼:
class GameplaySceneClass: SKScene, SKPhysicsContactDelegate {
private var player:Player?
private var center = CGFloat()
private var canMove = false, moveLeft = false
private var itemController = ItemController()
private var scoreLabel: SKLabelNode?
private var wordLabel: SKLabelNode?
private var score = 0
private var theWord = ""
private var vowelPressed = false
let correct = SoundSFX("correct.wav")
let wrong = SoundSFX("nomatch.wav")
let explosion = SoundSFX("explosion.wav")
var arrayOfStrings: [String]?
var theCheckedWord = ""
var currentCount = 0
var itemsArray = [String]()
var partialExists = false
var characterScore = 0
var onePointLetters = [12, 14, 18, 19, 20]
var twoPointLetters = [4, 7]
var threePointLetters = [2, 3, 13, 16]
var fourPointLetters = [6, 8, 22, 23, 25]
var fivePointLetters = [11]
var eightPointLetters = [10, 24]
var tenPointLetters = [17, 26]
var letter = 0
var scoreArray = [Int]()
var matchingTerms = [String]()
var gravity:CGFloat = -0.35
var result = CGSize()
let synth = AVSpeechSynthesizer()
var myUtterance = AVSpeechUtterance(string:"")
override func didMove(to view: SKView) {
SoundEngine.shared.backgroundMusicVolume = 1.0
SoundEngine.shared.playBackgroundMusic("Jungle Audio-1.m4a", loop: true)
initializeGame()
}
override func update(_ currentTime: TimeInterval) {
managePlayer()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location (in: self)
if atPoint(location).name == "LetterA" {
print ("Letter A pressed")
vowelPressed = true
theWord = theWord + "A"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterE" {
print ("Letter E pressed")
vowelPressed = true
theWord = theWord + "E"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterI" {
print ("Letter I pressed")
vowelPressed = true
theWord = theWord + "I"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterO" {
print ("Letter O pressed")
vowelPressed = true
theWord = theWord + "O"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterU" {
print ("Letter U pressed")
vowelPressed = true
theWord = theWord + "U"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "Pause" {
showPauseAlert()
}
else if atPoint(location).name == "delete" {
theWord = ""
theCheckedWord = ""
wordLabel?.text = theWord
}
else {
if location.x > center && !vowelPressed {
moveLeft = false
}
else if location.x < center && !vowelPressed {
moveLeft = true
}
canMove = true
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
canMove = false
}
func didBegin(_ contact: SKPhysicsContact) {
if !gamePaused {
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
if contact.bodyA.node?.name == "Player" {
firstBody = contact.bodyA
secondBody = contact.bodyB
}
else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.node?.name == "Player" && secondBody.node?.name == "Tile" {
letter = secondBody.node?.userData?.value(forKey:"key") as! Int
print ("The value of letter is \(letter)")
var letterCode = String(describing: letter)
var letterValue = Int(letterCode)
var finalLetterValue = letterValue!+64
var ASCIICode = Character(UnicodeScalar(finalLetterValue)!)
var letterString = String(describing:ASCIICode)
theWord = theWord + letterString
print (theWord)
if onePointLetters.contains(letter) {
characterScore += 1
}
else if twoPointLetters.contains(letter) {
characterScore += 2
}
else if threePointLetters.contains(letter) {
characterScore += 3
}
else if fourPointLetters.contains(letter) {
characterScore += 4
}
else if fivePointLetters.contains(letter) {
characterScore += 5
}
else if eightPointLetters.contains(letter) {
characterScore += 8
}
else if tenPointLetters.contains(letter) {
characterScore += 10
}
wordLabel?.text = theWord
theCheckedWord = theWord.lowercased()
print ("The checked word is \(theCheckedWord)")
checkWord()
secondBody.node?.removeFromParent()
}
if firstBody.node?.name == "Player" && secondBody.node?.name == "Bomb" {
explosion.play()
firstBody.node?.removeFromParent()
secondBody.node?.removeFromParent()
theWord = ""
score = 0
scoreLabel?.text = String(score)
var delayTimer = SKAction.wait(forDuration:1)
run (delayTimer)
restartGame()
}
}
}
private func initializeGame() {
do {
// This solution assumes you've got the file in your bundle
if let path = Bundle.main.path(forResource: "en", ofType: "txt"){
let data = try String(contentsOfFile:path, encoding: String.Encoding.utf8)
arrayOfStrings = data.components(separatedBy: "\n")
}
} catch let err as NSError {
// do something with Error
print(err)
}
physicsWorld.contactDelegate = self
physicsWorld.gravity = CGVector(dx:0,dy:gravity)
player = childNode(withName: "Player") as? Player!
player?.initializePlayer()
player?.position = CGPoint(x:0, y: -420)
scoreLabel = childNode(withName: "ScoreLabel") as? SKLabelNode!
scoreLabel?.text = String(score)
wordLabel = childNode(withName:"WordLabel") as? SKLabelNode!
wordLabel?.text = ""
center = self.frame.size.width/self.frame.size.height
var spawnBlocks = SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration:1),SKAction.run(spawnItems)]))
var removeBlocks = SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration:1),SKAction.run(removeItems)]))
if gamePaused == true {
self.scene?.isPaused = true
}
self.run(spawnBlocks)
self.run(removeBlocks)
}
private func checkWord() {
theCheckedWord = theWord.lowercased()
if (arrayOfStrings?.contains(theCheckedWord))! {
print ("Yes! \(theCheckedWord) is a word")
correct.play()
print ("The current value of score is \(score)")
score += characterScore
print ("Current gravity setting is \(gravity)")
scoreLabel?.text = String(score)
characterScore = 0
matchingTerms = (arrayOfStrings?.filter({$0.hasPrefix(theCheckedWord)
}))!
if matchingTerms.count == 1 {
characterScore = 0
print ("Current gravity setting is \(gravity)")
theWord = ""
theCheckedWord = ""
wordLabel?.text = ""
}
}
else if !(arrayOfStrings?.contains(theCheckedWord))! {
matchingTerms = (arrayOfStrings?.filter({$0.hasPrefix(theCheckedWord)
}))!
if matchingTerms.count == 0 {
wrong.play()
characterScore = 0
if score >= 5 {
score -= 5
}
theWord = ""
theCheckedWord = ""
wordLabel?.text = ""
}
}
}
這裏是我的敵人代碼:
import SpriteKit
struct ColliderType {
static let PLAYER: UInt32 = 0
static let TILE_AND_BOMB: UInt32 = 1;
}
public var bounds = UIScreen.main.bounds
public var width = bounds.size.width
public var height = bounds.size.height
class ItemController {
private var minX = CGFloat(-(width/2)), maxX = CGFloat(width/2)
private var vowelNumbers = [1, 5, 9, 15, 21]
func spawnItems() -> SKSpriteNode {
let item: SKSpriteNode?
if Int(randomBetweenNumbers(firstNum: 0, secondNum: 10)) > 7 {
item = SKSpriteNode(imageNamed: "Bomb")
item!.name = "Bomb"
item!.setScale(0.6)
item!.physicsBody = SKPhysicsBody(circleOfRadius: item!.size.height/2)
print ("The value of width is \(width)")
} else {
var num = Int(randomBetweenNumbers(firstNum: 1, secondNum: 26))
if vowelNumbers.contains(num) {
num = num + 1
}
item = SKSpriteNode(imageNamed: "Tile \(num)")
item?.userData = NSMutableDictionary()
item!.name = "Tile"
item!.userData!.setValue(num, forKey:"key")
item!.zRotation = 0
item!.setScale(0.9)
item!.physicsBody = SKPhysicsBody(circleOfRadius: item!.size.height/2)
if gamePaused == true {
item!.isPaused = true
}
else {
item!.isPaused = false
}
}
item!.physicsBody?.categoryBitMask = ColliderType.TILE_AND_BOMB;
item!.physicsBody?.isDynamic = true
item!.zPosition = 3
item!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
item!.position.x = randomBetweenNumbers(firstNum: minX, secondNum: maxX)
item!.position.y = 600
return item!
}
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat {
return CGFloat(arc4random())/CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum);
}
}
您可以在00:06和00看到滯後
這裏是我的播放器代碼:
import SpriteKit
class Player: SKSpriteNode {
private var minX = CGFloat(-300), maxX = CGFloat(300)
func initializePlayer() {
name = "Player"
physicsBody = SKPhysicsBody(circleOfRadius: size.height/2)
physicsBody?.affectedByGravity = false
physicsBody?.isDynamic = false
physicsBody?.categoryBitMask = ColliderType.PLAYER
physicsBody?.contactTestBitMask = ColliderType.TILE_AND_BOMB
}
func move(left:Bool){
if left {
position.x -= 15
if position.x < minX {
position.x = minX
}
}
else {
position.x += 15
if position.x > maxX {
position.x = maxX
}
}
}
}
這是否也發生在設備上? – BadgerBadger
「arrayOfStrings」中有多少個字符串? – nathan
此外......如果你使用了skspritenode的子類並添加了一個字母屬性或類似的東西,你的checkWords方法和你檢查字母的整個方法可能會更有效率。 – BadgerBadger