2017-04-13 41 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