【问题标题】:Implementing AI to Air Hockey in SpriteKIt?在 SpriteKIt 中将 AI 应用于空气曲棍球?
【发布时间】:2020-09-29 05:43:43
【问题描述】:

为了好玩和学习 Swift/Xcode,我正在 SpriteKit 中开发一款类似于空气曲棍球的游戏。我预计 AI 将是一个相当大的挑战,因为游戏中还有其他元素需要考虑。我知道我必须一个一个地处理每个问题。我已经为游戏创建了 2 人模式,现在我正在研究 AI。这是我用来计算和委托从木槌到冰球的冲动的一些代码(在 2 人模式下):

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
{
    bottomTouchIsActive = true
    var releventTouch:UITouch!
    //convert set to known type
    let touchSet = touches

    //get array of touches so we can loop through them
    let orderedTouches = Array(touchSet)


    for touch in orderedTouches
    {
        //if we've not yet found a relevent touch
        if releventTouch == nil
        {
            //look for a touch that is in the activeArea (Avoid touches by opponent)
            if activeArea.contains(CGPoint(x: touch.location(in: parent!).x, y: touch.location(in: parent!).y + frame.height * 0.24))
            {
                isUserInteractionEnabled = true
                releventTouch = touch
            }
            else
            {
                releventTouch = nil
            }
        }
    }

    if (releventTouch != nil)
    {
        //get touch position and relocate player
        let location = CGPoint(x: releventTouch!.location(in: parent!).x, y: releventTouch!.location(in: parent!).y + frame.height * 0.24)
        position = location

        //find old location and use pythagoras to determine length between both points
        let oldLocation = CGPoint(x: releventTouch!.previousLocation(in: parent!).x, y: releventTouch!.previousLocation(in: parent!).y + frame.height * 0.24)
        let xOffset = location.x - oldLocation.x
        let yOffset = location.y - oldLocation.y
        let vectorLength = sqrt(xOffset * xOffset + yOffset * yOffset)

        //get eleapsed and use to calculate speed6A
        if  lastTouchTimeStamp != nil
        {
            let seconds = releventTouch.timestamp - lastTouchTimeStamp!
            let velocity = 0.01 * Double(vectorLength) / seconds

            //to calculate the vector, the velcity needs to be converted to a CGFloat
            let velocityCGFloat = CGFloat(velocity)

            //calculate the impulse
            let directionVector = CGVector(dx: velocityCGFloat * xOffset / vectorLength, dy: velocityCGFloat * yOffset / vectorLength)

            //pass the vector to the scene (so it can apply an impulse to the puck)
            delegate?.bottomForce(directionVector, fromBottomPlayer: self)
            delegate?.bottomTouchIsActive(bottomTouchIsActive, fromBottomPlayer: self)
        }
        //update latest touch time for next calculation
        lastTouchTimeStamp = releventTouch.timestamp
    }
}

我想知道如何为 AI 转换此代码。我一直在向更新函数添加一些人工智能逻辑,我相信它也可以使用时间戳并计算帧之间的距离来计算脉冲。我只是不知道如何实现这个想法。非常感谢任何帮助:)

以下是我目前用于测试目的的一些基本代码,主要用于更新功能中的 AI 模式:

    if (ball?.position.y)! < frame.height / 2
    {
        if (botPlayer?.position.y)! < frame.height * 0.75
        {
            botPlayer?.position.y += 1
        }
    }
    else
    {
        if (botPlayer?.position.y)! > (ball?.position.y)!
        {
            if (botPlayer?.position.y)! - (ball?.position.y)! > frame.height * 0.1
            {
                botPlayer?.position.y -= 1
            }
            else
            {
                botPlayer?.position.y -= 3
            }
        }
        else
        {
            botPlayer?.position.y += 1
        }
    }
    if ((botPlayer?.position.x)! - (ball?.position.x)!) < 2
    {
        botPlayer?.position.x = (ball?.position.x)!
    }
    if (botPlayer?.position.x)! > (ball?.position.x)!
    {
        botPlayer?.position.x -= 2
    }
    else if (botPlayer?.position.x)! < (ball?.position.x)!
    {
        botPlayer?.position.x += 2
    }

【问题讨论】:

  • 您的问题过于宽泛,可能会获得接近投票。除此之外,尝试编码 AI 桨移动速度,难度越高。慢速=更多失误。更快的反应时间 = 更少的 AI 失误。

标签: swift xcode sprite-kit artificial-intelligence


【解决方案1】:

为了让 AI 做出决定,它必须拥有有关游戏状态的信息。为此,您可以编写一个函数来读取所有可用的游戏数据(冰球的位置、玩家得分、之前的移动等)并将状态作为字典返回。然后写一个函数来接受这个字典,并输出一个决定。考虑一下 Python 中的这个工作流程。

# we want the AI to make a decision

# start by grabbing game state
gameState = getGameState()

# pass this to the decision function
decision = getDecision( gameState )

# implement the decision
if decision == "move left":
    moveLeft()
else:
    moveRight()

这就是你要找的吗?

【讨论】:

  • 我喜欢这个想法,但它比我计划的要复杂一些。我不打算实施任何机器学习/预测 AI。我只是想实现一个能够做出逻辑决策并具有防御/攻击能力(更简单)的机器人。我如何使用时间(更新函数)和 AI 的距离变化来计算这个?我想转换顶部的代码块,以便能够计算方向矢量,并根据 AI 在 X 和 Y 方向的移动以及更新函数的增量时间,将其作为 AI 施加到冰球的脉冲。跨度>
  • 如果我理解正确的话,您想保留以前的距离变化和相应时间戳的记录,以便 AI 可以使用这些信息做出决定?如果是这样,您可以使用此数据的全局数组,并在需要时对其进行更新。然后,当您做出决定时,请检查全局数组以了解先前的动作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多