2017-04-13 68 views
0

我正在使用swift構建一款遊戲遊戲。目標是避免進入的寶石,並隨着關卡的增加獲得儘可能多的積分。石頭撞向船隻的方向相反。但我無法察覺船與石之間的碰撞,石頭穿過船。船可以向左或向右移動。我正在用swift構建一個遊戲遊戲。無法檢測到衝突

我用rect1.interects(rect2)作爲交集。

謝謝。

這裏是ViewController.swift

import UIKit 

class ViewController: UIViewController { 


@IBOutlet weak var moveWater: MovingWater! 

var boat:UIImageView! 
var stone:UIImageView! 
var boatLeftRight : UILongPressGestureRecognizer! 

var tapTimer:Timer! 

var leftM:UInt32 = 55 
var rightM:UInt32 = 250 

var leftS:UInt32 = 35 
var rightS:UInt32 = 220 

func startGame() { 
    boat = UIImageView(image: UIImage(named: "boat")) 
    boat.frame = CGRect(x: 0, y: 0, width: 60, height: 90) 
    boat.frame.origin.y = self.view.bounds.height - boat.frame.size.height - 10 
    boat.center.x = self.view.bounds.midX 

    self.view.insertSubview(boat, aboveSubview: moveWater) 

    boatLeftRight = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.leftRight(tap:))) 
    boatLeftRight.minimumPressDuration = 0.001 
    moveWater.addGestureRecognizer(boatLeftRight) 



} 

func leftRight(tap:UILongPressGestureRecognizer) { 


    if tap.state == UIGestureRecognizerState.ended { 
     if (tapTimer != nil) { 
      self.tapTimer.invalidate() 
     } 
    } else if tap.state == UIGestureRecognizerState.began { 
     let touch = tap.location(in: moveWater) 
     if touch.x > moveWater.frame.midX { 
      tapTimer = Timer.scheduledTimer(timeInterval: TimeInterval(0.005), target: self, selector: #selector(ViewController.moveBoat(time:)), userInfo: "right", repeats: true) 

     } else { 
      tapTimer = Timer.scheduledTimer(timeInterval: TimeInterval(0.005), target: self, selector: #selector(ViewController.moveBoat(time:)), userInfo: "left", repeats: true) 
     } 
    } 


} 

func moveBoat(time:Timer) { 

    if let d = time.userInfo as? String! { 
     var bot2 = boat.frame 

     if d == "right" { 
      if bot2.origin.x < CGFloat(rightM) { 
       bot2.origin.x += 2 
      } 



     } else { 
      if bot2.origin.x > CGFloat(leftM) { 
       bot2.origin.x -= 2 

      } 
     } 
     boat.frame = bot2 
    } 



} 

func movingStone() { 


    stone = UIImageView(image: UIImage(named: "stones.png")) 

    var stone2 = leftS + arc4random() % rightS 


    stone.bounds = CGRect(x:10, y:10, width:81.0, height:124.0) 
    stone.contentMode = .center; 
    stone.layer.position = CGPoint(x: Int(stone2), y: 10) 
    stone.transform = CGAffineTransform(rotationAngle: 3.142) 


    self.view.insertSubview(stone, aboveSubview: moveWater) 


    UIView.animate(withDuration: 5, delay: 0, options: UIViewAnimationOptions.curveLinear, animations: {() -> Void in 
     self.stone.frame.origin.y = self.view.bounds.height + self.stone.frame.height + 10 
    }) { (success:Bool) -> Void in 

     self.stone.removeFromSuperview() 
     self.movingStone() 

    } 



} 
func update() { 
if(boat.bounds.intersects(stone.bounds)) { 
    boat.image = //set new image 
    } 
} 


override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 
    moveWater.backgroundStart() 
    startGame() 
    movingStone() 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

}

+1

有許多問題,我可以在你的方法見: - 缺少遊戲主循環,每個遊戲的實體將關於獲得至少更新到位置 - 混合幀座標 - 碰撞將不得不從頭開始做的, uiview.bounds不一定與用戶體驗視角衝突盒中的優化重疊 我推薦的是: - 查找一些教程如何設計遊戲 - 切換到SpriteKit,它會給你「物理」免費 –

+0

爲什麼我不能使用碰撞檢測。我不知道爲什麼我無法檢測到碰撞! –

+0

使用框架,您只能輕鬆檢測到矩形碰撞,如果您將碰撞矩形設置得很小(比我認爲的小),但無法檢測到以此方式相交的自定義形狀。 –

回答

0

我解決了這個問題我自己。這很容易,沒有任何SpriteKit,我已經檢測到碰撞。

func intersectsAt(tap2 : Timer) { 


    var f1 : CGRect! 
    var f2 : CGRect! 

    f1 = boat.layer.presentation()?.frame 
    f2 = stone.layer.presentation()?.frame 
    if(f1.intersects(f2)) { 
     stopGame() 

    } 

} 
+0

對於遊戲更新循環而言,使用計時器並不是一個好習慣,從長遠來看,這會導致您遇到大問題。請參閱下面的答案。 – BadgerBadger

2

你選擇UIKit來製作遊戲的任何原因?

如果你製作遊戲,你應該使用SpriteKit而不是UIKit。

檢查谷歌和youtube的SpriteKit教程,有負載。

一個非常良好的開端是這樣一個教你SpriteKit場景編輯器的基礎知識以及如何做碰撞等

https://www.raywenderlich.com/118225/introduction-sprite-kit-scene-editor

我建議你不要繼續這樣下去。

希望這會有幫助

+0

我想以基本的方式實施。就是這樣,我會繼續使用SpriteKit等。 –

+0

是的,你在做什麼沒有什麼直接的錯誤。但你也可以使用正確的工具來製作遊戲。它會讓你的生活變得更輕鬆,併爲你提供更多的可能性來製作遊戲。 – crashoverride777

+0

嘿,我有一個疑問。我怎樣才能讓石頭在船的位置出現?任何想法?如果機器人在左邊,那麼當它開始生成動畫時,石頭應該顯示爲左側,並且當它朝向右側時,石頭顯示正確。 –

2

我看到了你自己的答案。這確實是基本的碰撞檢測。你仍然應該看看SpriteKit。我發現你使用的是Timer,這不是最好的方法,因爲Timers會長期爲你提供性能問題。當你開始遊戲開發時,這是一個常見的錯誤。

也許你認爲你可以通過設置一個非常快的定時器來確保幀速率。事情是定時器不一致,它們的優先級也很低。這意味着如果在後臺發生更重要的事情,您的計時器呼叫將被延遲。如果您的移動是基於強制刷新率,它會很快變得波濤洶涌。此外,您在計時器中運行的代碼可能會更快或更慢,這取決於您使用的邏輯。

SpriteKit爲您提供了一個更新函數,每幀都運行一次,讓您瞭解每一幀的當前系統時間。通過跟蹤該值,您可以計算兩幀之間的時間間隔,然後您可以相應地縮放移動以補償兩幀之間的時間差。

最重要的是,SpriteKit爲您提供了一系列用於碰撞檢測和移動的選項。它集成了一個非常好的物理引擎和碰撞檢測系統。它也將對複雜形狀進行碰撞檢測,對身體施加力量等。

我強烈建議您按照上面的答案給出的Ray Wenderlich的網站鏈接。如果你有預算,你可能還想購買他們關於如何爲蘋果設備製作2D遊戲的書。我已閱讀封面封面,我可以說我喜歡它。我現在可以用SpriteKit做我自己的東西,它也是新手迅速發展的一個很好的入門者。

+0

雅我已經通過SpriteKit和所有這是我的實現,我想以一種基本的方式編碼。現在我一定會切換到gameEngines。 謝謝。 –

+0

很好的答案! Upvoted – crashoverride777

+0

@PrasannaVigneshwar:你會很快看到SpriteKit是非常基本的東西,比如玩樂句。 XCode的編輯器可以讓你直觀地設計很多東西,儘管它不如Interface Builder那麼成熟,但它仍然很好,它可以讓你重用很多東西。將代碼的內容和設計分開,使事物變得模塊化和可重用,也是非常好的。 – BadgerBadger