我正在使用swift构建一个游戏。无法检测到碰撞

时间:2017-04-13 05:51:09

标签: ios 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.
}

}

3 个答案:

答案 0 :(得分:2)

您选择UIKit制作游戏的原因是什么?

如果你制作游戏,你应该使用SpriteKit而不是UIKit。

检查google和youtube上的SpriteKit教程,有负载。

这是一个非常好的开始,它教你SpriteKit场景编辑器的基础知识以及如何进行碰撞等。

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

我建议你不要这样继续。

希望这有帮助

答案 1 :(得分:2)

我看到了你自己的答案。这确实是基本的碰撞检测。你还应该看看SpriteKit。我发现你使用的是计时器,这不是最好的方法,因为从长远来看,计时器会给你性能问题。当你开始游戏开发时,这是一个常见的错误。

也许您认为可以通过设置非常快的计时器来确保帧速率。问题是计时器不一致,也没有优先级。这意味着如果在后台发生更重要的事情,您的计时器呼叫将被延迟。如果您的移动基于强制刷新率,则会很快变得不稳定。此外,您在计时器中运行的代码可能会更快或更慢,具体取决于您使用的逻辑。

SpriteKit为您提供了每帧运行的更新功能,让您了解每一帧的当前系统时间。通过跟踪该值,您可以计算两帧之间的时间,然后可以相应地缩放您的移动以补偿两帧之间的时差。

除此之外,SpriteKit为您提供了一系列用于碰撞检测和移动的选项。它集成了一个制作精良的物理引擎和碰撞检测系统。它还将对复杂形状进行碰撞检测,对物体施加力等等。

我强烈建议您点击上面答案中给您的Ray Wenderlich网站的链接。如果您有预算,您可能还想购买有关如何为Apple设备制作2D游戏的书籍。我已经阅读了封面封面,我可以说我喜欢它。我现在可以用SpriteKit做自己的东西了,对于新手来说,它也是一个非常好的开端。

答案 2 :(得分: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()

    }

}