将 SKSpriteNode 移动到触摸位置

2023-12-02

enter image description here

上面是我的游戏的图像。一个自上而下的游戏。无论玩家触摸屏幕上的哪个位置,我都希望子弹在一段时间内到达该位置。我还希望玩家能够在屏幕上拖动手指,同样的事情也会发生。这样玩家就不必每次想要射击时都触摸屏幕。

到目前为止我已经尝试了一些不同的东西,但似乎没有任何效果。

首先,我不知道是否应该为子弹提供单独的功能。但无论如何,这是我的子弹功能。

func spawnBullets() {
    let bullet = SKSpriteNode(imageNamed: "Bullet")
    bullet.name = "Bullet"
    bullet.zPosition = 4
    bullet.position = CGPoint(x: player.position.x + 19, y: 
    player.position.y)
    self.addChild(bullet)
}

我在 didMove 函数中还有一个用于子弹的“计时器”:

var timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, 
selector: Selector("spawnBullets"), userInfo: nil, repeats: true)

最后,这是我的 TouchBegan 函数:

override func touchesBegan(_ touches: Set<UITouch>, with event: 
UIEvent?) {        
    for  touch in touches {            
        let location = touch.location(in: self)            
        let moveToPoint = SKAction.move(to: location, duration: 0.5)
        let repeatAction = SKAction.repeatForever(moveToPoint)            
        bullet.run(moveToPoint)
    }

}

给你 - 一个简单的应用程序,其中有一艘船,你可以在屏幕上拖动,导弹会射向触摸的位置。

如果你触摸了船,你可以拖动它;触摸船外,导弹将从船上发射到触摸位置。

import SpriteKit

class GameScene: SKScene {

var ship = SKSpriteNode()
var shipIsTouched = false
var missileDestination = CGPoint()
let missileSpeed: CGFloat = 800 // Points per second)
let missileFireRate : TimeInterval = 0.2 // Seconds between each missile

override func didMove(to view: SKView) {
    missileDestination = CGPoint(x: 0, y: (self.size.height / 2))
    createPlayerShip()
    let fire = SKAction.sequence([SKAction.run(fireMissile), SKAction.wait(forDuration: missileFireRate)])
    run(SKAction.repeatForever(fire))
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if ship.contains(touch.location(in: self)) {
            shipIsTouched = true
        } else {
            missileDestination = touch.location(in: self)
            ship.zRotation = direction(to: missileDestination, from: ship.position) - CGFloat(Double.pi/2)
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if (shipIsTouched == true) {
        ship.position = (touches.first?.location(in: self))!
        ship.zRotation = direction(to: missileDestination, from: ship.position) - CGFloat(Double.pi/2)
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if shipIsTouched {
        shipIsTouched = false
    }
}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
}

func createPlayerShip() {
    ship = SKSpriteNode(imageNamed: "Spaceship")
    ship.zRotation = CGFloat(-Double.pi/2.0)
    ship.scale(to: CGSize(width: 150, height: 150))
    ship.position = CGPoint(x: -size.width/2 + 200, y: 0)

    addChild(ship)
}


func fireMissile() {
    let missile = SKSpriteNode(color: .white, size: CGSize(width: 50, height: 10))
    missile.position = ship.position

    let missileFlightTime = travelTime(to: missileDestination, from: ship.position, atSpeed: missileSpeed)
    missile.zRotation = direction(to: missileDestination, from: missile.position)

    addChild(missile)

    let missileMove = SKAction.move(to: missileDestination,
                                    duration: TimeInterval(missileFlightTime))
    let missileRemove = SKAction.removeFromParent()
    missile.run(SKAction.sequence([missileMove, missileRemove]))
}

func travelTime(to target : CGPoint, from : CGPoint, atSpeed speed : CGFloat) -> TimeInterval {
    let distance = sqrt(pow(abs(target.x - from.x),2) +
        pow(abs(target.y - from.y),2))
    return TimeInterval(distance/speed)
}


func direction(to target : CGPoint, from: CGPoint) -> CGFloat {
    let x = target.x - from.x
    let y = target.y - from.y
    var angle = atan(y / x)
    if x < 0 {
        angle = angle + CGFloat.pi
    }
    return angle
}
}

有一些额外的技巧可以使导弹速度一致(因为 moveTo 需要时间,而不是速度,所以如果目的地很近,导弹会缓慢移动,如果距离较远,导弹会移动得更快)并让导弹旋转以面对目的地。

您可以为导弹创建一条弯曲的路径以跟随其到达目的地,这看起来很酷,但可能不适合您的应用程序。

EDIT:

如果您希望船静止不动,并且导弹跟随您的手指,请将所有代码替换为createPlayerShip有了这个(是的,我们失去了touchesEnded() and update():

import SpriteKit

class GameScene: SKScene {

var ship = SKSpriteNode()
var missileDestination = CGPoint()
let missileSpeed: CGFloat = 800 // Points per second)
let missileFireRate : TimeInterval = 0.2 // Seconds between each missile

override func didMove(to view: SKView) {
    missileDestination = CGPoint(x: size.height/2, y: 0)
    createPlayerShip()
    let fire = SKAction.sequence([SKAction.run(fireMissile), SKAction.wait(forDuration: missileFireRate)])
    run(SKAction.repeatForever(fire))
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
            missileDestination = touch.location(in: self)
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        missileDestination = (touches.first?.location(in: self))!
} 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 SKSpriteNode 移动到触摸位置 的相关文章

  • 保存来自 TrueDepth 相机的深度图像

    我正在尝试保存 iPhone X TrueDepth 相机的深度图像 使用AVCam照片滤镜 https developer apple com library content samplecode AVCamPhotoFilter Lis
  • 使用 BGTaskScheduler 进行后台获取与调试模拟完美配合,但在实践中却不起作用

    我在 appDelegate 的 didFinishLaunchingWithOptions 中注册后台获取任务 BGTaskScheduler shared register forTaskWithIdentifier Backgroun
  • XCode 7 中的 AWSS3TransferManagerUploadRequest

    我今天升级到 Xcode 7 Swift 2 0 我的项目正在使用 CocoaPods 我正在 POD 文件中导入所有与 AWS 相关的文件 我已经设置了桥接标头 并导入了 Amazon 告诉我的所有文件 在升级到 Swift 2 0 之前
  • 如何观察UserDefaults的变化?

    我有一个 ObservedObject在我看来 struct HomeView View ObservedObject var station Station var body some View Text self station sta
  • 具有动态警报正文的快速本地通知

    所以我可以创建一个像这样的本地通知 var localNotification UILocalNotification localNotification fireDate NSDate timeIntervalSinceNow 7 loc
  • 删除派生数据文件夹后,Xcode 不断重新创建派生数据文件夹

    自动完成功能在 Xcode 6 中不再起作用 我四处搜索 发现删除派生数据文件夹可以解决此问题 每次我删除它时 它都会回来 然后就不会再自动完成了 有什么建议么 Thanks 没关系 我解决了这个问题 我没有声明需要在类内的方法中使用的变量
  • 为 Swift 对象/属性设置观察者

    我一直在寻找一种在连接到 Mac 的显示器数量发生变化时触发方法的方法 我知道我可以获得 NSScreen screens count 的值 但我需要找到一种方法来在该值发生变化时创建通知或其他内容 或者指示所连接的显示器数量发生变化的其他
  • 如何右对齐 UILabel?

    Remark 实施 myLabel textAlignment right does not解决了我的问题 这不是我所要求的 我想要实现的是让标签对齐右对齐 为了更清楚地说明 这就是如何left对齐外观 就是这样justify对齐外观 if
  • Swift 3 中的 JSON 解析

    有没有人能够找到一种在 Swift 3 中解析 JSON 文件的方法 我已经能够返回数据 但在将数据分解为特定字段时我没有成功 我会发布示例代码 但我已经尝试了很多不同的方法但没有成功 并且没有保存任何代码 我想要解析的基本格式是这样的 提
  • 以编程方式从底部裁剪图像

    我正在开发自定义相机应用程序 一切进展顺利 但我在从底部裁剪图像时遇到了问题 即 裁剪后的图像与原始图像具有完全相同的宽度 但高度将为原始图像的 1 3 并且必须从底部开始 斯威夫特3解决方案 func cropBottomImage im
  • Swift 中的柯里函数

    我想创建一个返回柯里函数的函数 如下所示 func addTwoNumbers a Int b Int gt Int return a b addTwoNumbers 4 b 6 Result 10 var add4 addTwoNumbe
  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • iOS 电池监控 Swift

    我已将监控设置为启用 但模拟器和设备中的电池电量仍然为 1 UIDevice currentDevice batteryMonitoringEnabled true var level UIDevice currentDevice batt
  • 设置/覆盖 UICollectionView 中单元格之间的填充

    我有一个 UICollectionView 但在获取单元格之间的填充时遇到了问题 理论上 我应该能够将屏幕除以 4 并且我可以获得包含 4 个图像的单元格大小 完美地占据屏幕宽度 但是 它选择不这样做 相反 它会创建 3 个具有巨大填充的图
  • 用于字数计算的 Swift String 中的字数

    我想做一个程序来找出字符串中有多少个单词 用空格 逗号或其他字符分隔 然后把总数加起来 我正在制作一个平均计算器 所以我想要数据总数 然后将所有单词相加 update Xcode 10 2 x Swift 5 或更高版本 使用基础方法enu
  • 当 UITextField 已满或空时显示警报 Swift

    下面的代码中 如果 userNameTF 或 passwordTF 已满或为空 则会显示警报 IBAction func LoginBtn sender AnyObject let userName userNameTF text let
  • IPV6 快速可达性

    我是 swift 和 xcode 的新手 并且我的应用程序因 IPV6 而被拒绝 性能 2 1 当我们执行以下操作时 您的应用程序会在运行 iOS 9 3 5 并连接到 IPv6 网络的 iPad 和 iPhone 上崩溃 具体来说 当我们
  • CGPoint 标量乘法 Swift

    我正在 SpriteKit 中构建一个平台游戏 并将为我的实体实现更新功能 以便它们根据重力和速度移动 但是 我需要使添加的速度量与增量时间成比例 以防止帧速率影响我的实体的移动方式 因此我将导入 GLKit 以便我可以使用标量函数 但是
  • 使用 UISearchBar 过滤数组

    我目前正在使用以下代码来过滤数组并将结果显示在我的 tableView 中 问题是 只有当搜索与确切的单词匹配时 才会返回结果 如何更改数组过滤器以在输入时搜索每个字符 let data Mango Grape Berry Orange A
  • iOS 13 beta 外部屏幕上的 OverscanCompensation

    我正在测试一个应用程序的测试版 但遇到了外部屏幕的问题 我们看到应用程序周围有黑色边框 我们之前可以通过设置来纠正它overscanCompensation to none但在 iOS 13 中 该设置根本没有任何效果 我们曾经看到一个错误

随机推荐

  • 带有 C# ImageFormat 类的 WebP 图像

    我正在从网络下载图像以将其保存在本地 它适用于任何其他图像格式 但当我尝试读取 WebP 图像时 下面的方法会失败并出现参数异常 private static Image GetImage string url try HttpWebReq
  • 包容性和排除性的区别?

    我觉得这是一个简单的概念 但我在包容性和排他性方面遇到了麻烦 特别是关于随机数生成器 例如 如果我想要一个值 2 8 包括 2 和 8 那么这将是包容性的 对吗 该代码看起来怎么样 像这样的事情 nextInt 8 2 2 例如 如果我想要
  • 从一元数据创建二元(关系)数据

    我的冲突数据看起来像这样 conflict ID country code SideA 1 1 1 1 2 1 1 3 0 2 4 1 2 5 0 现在我想将其变成如下所示的二元冲突数据 SideA 1 应该是country code 1
  • 如何使用 PHP 创建随机字符串?

    我知道 PHP 中的 rand 函数生成随机整数 但是生成随机字符串的最佳方法是什么 例如 原始字符串 9 个字符 string abcdefghi 限制为 6 个字符的随机字符串示例 string ibfeca 更新 我发现了大量这些类型
  • 使用 documentFragment 的 IE 性能不佳

    为了测试 DOM 操作与innerHTML 我使用了这个小测试方法documentFragment web page 追加 10000href元素到一个div元素 对于 Chrome 或 Firefox 性能还可以 但在 IE 10 9 8
  • PhpStorm 和 XAMPP - 调试未启动

    我在使用 PhpStorm 调试器时遇到了困难 我阅读了他们所有的文档 并且我已经正确设置了调试 根据phpinfo 调试定制安装报告和 PhpStorm 分析 但是 无论我尝试什么 调试器都不会触发 我的设置如下 我将 XAMPP 文档根
  • 如何传递定义为常量的数组的引用?

    我定义了哈希和数组常量 当将它们传递给函数时 我必须将它们作为引用传递 不过我想知道正确的语法是什么 考虑这个例子 usr bin perl use strict use warnings use constant AC gt qw a b
  • 使用 sqlalchemy 查询特定 JSON 列 (postgres)

    我有一个带有 JSON 字段的模型 class Item db Model data db Column JSON nullable False 数据包含一些 JSON 例如 cost 10 00 passengers 2 surcharg
  • 后台代理静态变量值不同

    我有一个应用程序 可以显示一些数据并启动后台代理来动态更新动态图块 由于动态图块内容是在后台代理中使用从主线程填充的一些变量创建的 因此我决定 也许这是一个错误的决定 但这是我认为唯一合理的决定 编写一个具有静态变量和属性的类以在主线程之间
  • Laravel 5.3 使用自定义验证

    我使用 Laravel 5 3 我想使用表单验证来测试用户密码的哈希值 这是我的代码 validator Validator make request gt all old password gt required max 20 min 6
  • jpa返回哪些集合?

    JPA 在本例中为 Eclipselink 是否总是返回 IndirectList 其中实体有一个列表 该列表可以吗 或者应该将其转换为另一个列表 可能是链接列表 Analysis 如果我们看一下 EclipseLink 的间接列表的 AP
  • 即使在呈现模式视图控制器时如何保持键盘存在?

    我已经显示了一个模态视图控制器 并且 UITextView 成为第一响应者并显示键盘 加载此屏幕后 用户可以在提交之前对其输入进行分类 这是通过顶部呈现的另一个模态视图控制器来实现的 当第二个出现时 键盘将消失 用户进行选择 然后当初始 U
  • std::remove() 按预期使用文字,但不适用于取消引用的迭代器

    在学习删除 擦除惯用语的同时 以及了解 std min element 的工作原理如何在 C 17 中使用 std min element 我想尝试从以下代码中删除最小元素 include
  • 从 S3 通配符加载文件时发生 Spark 错误

    我正在使用 pyspark shell 并尝试使用 Spark 的文件通配符功能从 S3 读取数据 但出现以下错误 Welcome to version 1 2 0 Using Python version 2 7 6 default Ju
  • 为什么此代码会抛出 Facebook API 错误 191?

    我有以下 config php 文件位于 www sitename com facebook
  • 地理围栏:如何使用 Oracle Spatial 查找点或形状是否在多边形内

    如何使用 Oracle 空间 SQL 查询查找点或多边形是否在另一个多边形内 这是场景 我有一个表 STATE TABLE 其中包含一个空间类型 sdo geometry 它是一个多边形 比如说一个州 我有另一个表 UNIVERSITY T
  • 使用从多个表中选择的内容创建烧瓶表单

    我看过大量的教程 这些教程显示了使用 Flask 和 flash wtf 的登录表单 但没有一个教程是从数据库表值填充多个选择框的 这就是我正在尝试做的 一个简单的注册表 名 姓 地址第一行 地址行 2 City 状态 Id 从 Id 状态
  • Grails:在某些路径上禁用 Spring Security Core

    如何设置 Spring Security Core 以不过滤对特定模式 例如 api 的调用 grails plugins springsecurity filterChain chainMap api JOINED FILTERS 不起作
  • 确定当前调用堆栈(用于诊断目的)

    出于诊断目的 我有时需要存储导致给定状态转换的调用堆栈 例如授予锁 提交事务等 以便以后出现问题时我可以找出最初触发状态转换的人 目前 我知道检索调用堆栈的唯一方法类似于以下代码片段 我认为它非常丑陋 StackTraceElement c
  • 将 SKSpriteNode 移动到触摸位置

    上面是我的游戏的图像 一个自上而下的游戏 无论玩家触摸屏幕上的哪个位置 我都希望子弹在一段时间内到达该位置 我还希望玩家能够在屏幕上拖动手指 同样的事情也会发生 这样玩家就不必每次想要射击时都触摸屏幕 到目前为止我已经尝试了一些不同的东西