⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 steeringbehavior.vb

📁 一个.Net下用VB编写的用于游戏的人工智能引擎
💻 VB
📖 第 1 页 / 共 5 页
字号:
    '// -- Group Behaviors -- //

    '//-------------------------------- Cohesion ------------------------------
    '//
    '//  returns a steering force that attempts to move the agent towards the
    '//  center of mass of the agents in its immediate area
    '//------------------------------------------------------------------------
    Private Function Cohesion(ByVal neighbors As ArrayList) As Vector2D
        '//first find the center of mass of all the agents
        Dim CenterOfMass, SteeringForce As Vector2D

        Dim NeighborCount As Integer = 0

        '//iterate through the neighbors and sum up all the position vectors
        Dim a As Integer
        For a = 0 To neighbors.Count - 1
            '//make sure *this* agent isn't included in the calculations and that
            '//the agent being examined is close enough ***also make sure it doesn't
            '//include the evade target ***
            If (Not neighbors(a) Is m_pVehicle) And CType(neighbors(a), Vehicle).IsTagged() And (Not neighbors(a) Is m_pTargetAgent1) Then
                CenterOfMass.PlusEqual(CType(neighbors(a), Vehicle).Pos())
                NeighborCount += 1
            End If
        Next

        If NeighborCount > 0 Then
            '//the center of mass is the average of the sum of positions
            CenterOfMass.DividedEqual(CDbl(NeighborCount))

            '//now seek towards that position
            SteeringForce = Seek(CenterOfMass)
        End If

        '//the magnitude of cohesion is usually much larger than separation or
        '//allignment so it usually helps to normalize it.
        Return Vector2D.Vec2DNormalize(SteeringForce)
    End Function

    '//---------------------------- Separation --------------------------------
    '//
    '// this calculates a force repelling from the other neighbors
    '//------------------------------------------------------------------------
    Private Function Separation(ByVal neighbors As ArrayList) As Vector2D
        Dim SteeringForce As Vector2D
        Dim a As Integer
        For a = 0 To neighbors.Count - 1
            '//make sure this agent isn't included in the calculations and that
            '//the agent being examined is close enough. ***also make sure it doesn't
            '//include the evade target ***
            If (Not neighbors(a) Is m_pVehicle) And CType(neighbors(a), Vehicle).IsTagged() And (Not neighbors(a) Is m_pTargetAgent1) Then
                Dim ToAgent As Vector2D = m_pVehicle.Pos().Minus(CType(neighbors(a), Vehicle).Pos())

                '//scale the force inversely proportional to the agents distance  
                '//from its neighbor.
                SteeringForce.PlusEqual(Vector2D.Vec2DNormalize(ToAgent).Divided(ToAgent.Length()))
            End If
        Next

        Return SteeringForce

    End Function

    '//---------------------------- Alignment ---------------------------------
    '//
    '//  returns a force that attempts to align this agents heading with that
    '//  of its neighbors
    '//------------------------------------------------------------------------
    Private Function Alignment(ByVal neighbors As ArrayList) As Vector2D
        '//used to record the average heading of the neighbors
        Dim AverageHeading As Vector2D

        '//used to count the number of vehicles in the neighborhood
        Dim NeighborCount As Integer = 0

        '//iterate through all the tagged vehicles and sum their heading vectors  
        Dim a As Integer
        For a = 0 To neighbors.Count - 1
            '//make sure *this* agent isn't included in the calculations and that
            '//the agent being examined  is close enough ***also make sure it doesn't
            '//include any evade target ***
            If (Not neighbors(a) Is m_pVehicle) And CType(neighbors(a), Vehicle).IsTagged() And (Not neighbors(a) Is m_pTargetAgent1) Then
                AverageHeading.PlusEqual(CType(neighbors(a), Vehicle).Heading())
                NeighborCount += 1
            End If
        Next

        '//if the neighborhood contained one or more vehicles, average their
        '//heading vectors.
        If (NeighborCount > 0) Then
            AverageHeading.DividedEqual(CDbl(NeighborCount))
            AverageHeading.MinusEqual(m_pVehicle.Heading())
        End If

        Return AverageHeading
    End Function

    '//the following three are the same as above but they use cell-space
    '//partitioning to find the neighbors
    '//-------------------------------- Cohesion ------------------------------
    '//
    '//  returns a steering force that attempts to move the agent towards the
    '//  center of mass of the agents in its immediate area
    '//
    '//  USES SPACIAL PARTITIONING
    '//------------------------------------------------------------------------
    Private Function CohesionPlus(ByVal neighbors As ArrayList) As Vector2D
        '//first find the center of mass of all the agents
        Dim CenterOfMass, SteeringForce As Vector2D

        Dim NeighborCount As Integer = 0

        '//iterate through the neighbors and sum up all the position vectors
        Dim i As Integer
        Dim pV As Vehicle
        For i = 0 To m_pVehicle.World.CellSpace.Neighbors.Count - 1
            '//make sure *this* agent isn't included in the calculations and that
            '//the agent being examined is close enough
            pV = m_pVehicle.World.CellSpace.Neighbors(i)
            If Not pV Is m_pVehicle Then
                Dim ToAgent As Vector2D = m_pVehicle.Pos().Plus(pV.Pos())

                '//scale the force inversely proportional to the agents distance  
                '//from its neighbor.
                CenterOfMass.PlusEqual(pV.Heading)
                NeighborCount += 1
            End If

        Next

        If (NeighborCount > 0) Then
            '//the center of mass is the average of the sum of positions
            CenterOfMass.DividedEqual(CDbl(NeighborCount))

            '//now seek towards that position
            SteeringForce = Seek(CenterOfMass)
        End If

        '//the magnitude of cohesion is usually much larger than separation or
        '//allignment so it usually helps to normalize it.
        Return Vector2D.Vec2DNormalize(SteeringForce)

    End Function

    '//---------------------------- Separation --------------------------------
    '//
    '// this calculates a force repelling from the other neighbors
    '//
    '//  USES SPACIAL PARTITIONING
    '//------------------------------------------------------------------------
    Private Function SeparationPlus(ByVal agents As ArrayList) As Vector2D
        Dim SteeringForce As Vector2D

        '//iterate through the neighbors and sum up all the position vectors
        Dim i As Integer
        Dim pV As Vehicle
        For i = 0 To m_pVehicle.World.CellSpace.Neighbors.Count - 1
            '//make sure this agent isn't included in the calculations and that
            '//the agent being examined is close enough
            pV = m_pVehicle.World.CellSpace.Neighbors(i)
            If Not pV Is m_pVehicle Then
                Dim ToAgent As Vector2D = m_pVehicle.Pos().Plus(pV.Pos())

                '//scale the force inversely proportional to the agents distance  
                '//from its neighbor.
                SteeringForce.PlusEqual(Vector2D.Vec2DNormalize(ToAgent).Divided(ToAgent.Length()))
            End If

        Next

        Return SteeringForce
    End Function
    '//---------------------------- Alignment ---------------------------------
    '//
    '//  returns a force that attempts to align this agents heading with that
    '//  of its neighbors
    '//
    '//  USES SPACIAL PARTITIONING
    '//------------------------------------------------------------------------
    Private Function AlignmentPlus(ByVal agents As ArrayList) As Vector2D
        '//This will record the average heading of the neighbors
        Dim AverageHeading As Vector2D

        '//This count the number of vehicles in the neighborhood
        Dim NeighborCount As Double = 0.0

        '//iterate through the neighbors and sum up all the position vectors
        Dim i As Integer
        Dim pV As Vehicle
        For i = 0 To m_pVehicle.World.CellSpace.Neighbors.Count - 1
            '//make sure this agent isn't included in the calculations and that
            '//the agent being examined is close enough
            pV = m_pVehicle.World.CellSpace.Neighbors(i)
            If Not pV Is m_pVehicle Then
                Dim ToAgent As Vector2D = m_pVehicle.Pos().Plus(pV.Pos())

                AverageHeading.PlusEqual(pV.Heading)
                NeighborCount += 1
            End If

        Next


        '//if the neighborhood contained one or more vehicles, average their
        '//heading vectors.
        If (NeighborCount > 0.0) Then
            AverageHeading.DividedEqual(NeighborCount)
            AverageHeading.MinusEqual(m_pVehicle.Heading())
        End If

        Return AverageHeading

    End Function

    '/* .......................................................

    '                       END BEHAVIOR DECLARATIONS

    '.......................................................*/

    '//calculates and sums the steering forces from any active behaviors
    '//---------------------- CalculateWeightedSum ----------------------------
    '//
    '//  this simply sums up all the active behaviors X their weights and 
    '//  truncates the result to the max available steering force before 
    '//  returning
    '//------------------------------------------------------------------------
    Private Function CalculateWeightedSum() As Vector2D
        If IsOn(behavior_type.wall_avoidance) Then
            m_vSteeringForce.PlusEqual(WallAvoidance(m_pVehicle.World().Walls()).Mutiply(m_dWeightWallAvoidance))
        End If

        If IsOn(behavior_type.obstacle_avoidance) Then
            m_vSteeringForce.PlusEqual(ObstacleAvoidance(m_pVehicle.World().Obstacles()).Mutiply(m_dWeightObstacleAvoidance))
        End If

        If IsOn(behavior_type.evade) Then
            'assert(m_pTargetAgent1 && "Evade target not assigned");
            m_vSteeringForce.PlusEqual(Evade(m_pTargetAgent1).Mutiply(m_dWeightEvade))
        End If

        '//these next three can be combined for flocking behavior (wander is
        '//also a good behavior to add into this mix)
        If Not isSpacePartitioningOn() Then
            If IsOn(behavior_type.separation) Then
                m_vSteeringForce.PlusEqual(Separation(m_pVehicle.World().Agents()).Mutiply(m_dWeightSeparation))
            End If

            If IsOn(behavior_type.allignment) Then
                m_vSteeringForce.PlusEqual(Alignment(m_pVehicle.World().Agents()).Mutiply(m_dWeightAlignment))
            End If

            If IsOn(behavior_type.cohesion) Then
                m_vSteeringForce.PlusEqual(Cohesion(m_pVehicle.World().Agents()).Mutiply(m_dWeightCohesion))
            End If
        Else
            If IsOn(behavior_type.separation) Then
                m_vSteeringForce.PlusEqual(SeparationPlus(m_pVehicle.World().Agents()).Mutiply(m_dWeightSeparation))
            End If

            If IsOn(behavior_type.allignment) Then
                m_vSteeringForce.PlusEqual(AlignmentPlus(m_pVehicle.World().Agents()).Mutiply(m_dWeightAlignment))
            End If

            If IsOn(behavior_type.cohesion) Then
                m_vSteeringForce.PlusEqual(CohesionPlus(m_pVehicle.World().Agents()).Mutiply(m_dWeightCohesion))
            End If
        End If

        If IsOn(behavior_type.wander) Then
            m_vSteeringForce.PlusEqual(Wander().Mutiply(m_dWeightWander))
        End If

        If IsOn(behavior_type.seek) Then
            m_vSteeringForce.PlusEqual(Seek(m_pVehicle.World().Crosshair()).Mutiply(m_dWeightSeek))
        End If

        If IsOn(behavior_type.flee) Then
            m_vSteeringForce.PlusEqual(Flee(m_pVehicle.World().Crosshair()).Mutiply(m_dWeightFlee))
        End If

        If IsOn(behavior_type.arrive) Then
            m_vSteeringForce.PlusEqual(Arrive(m_pVehicle.World().Crosshair(), m_Deceleration).Mutiply(m_dWeightArrive))
        End If

        If IsOn(behavior_type.pursuit) Then
            'assert(m_pTargetAgent1 && "pursuit target not assigned");
            m_vSteeringForce.PlusEqual(Pursuit(m_pTargetAgent1).Mutiply(m_dWeightPursuit))
        End If

        If IsOn(behavior_type.offset_pursuit) Then
            'assert (m_pTargetAgent1 && "pursuit target not assigned");
            'assert (!m_vOffset.isZero() && "No offset assigned");
            m_vSteeringForce.PlusEqual(OffsetPursuit(m_pTargetAgent1, m_vOffset).Mutiply(m_dWeightOffsetPursuit))
        End If

        If IsOn(behavior_type.interpose) Then
            'assert (m_pTargetAgent1 && m_pTargetAgent2 && "Interpose agents not assigned");
            m_vSteeringForce.PlusEqual(Interpose(m_pTargetAgent1, m_pTargetAgent2).Mutiply(m_dWeightInterpose))
        End If

        If IsOn(behavior_type.hide) Then
            'assert(m_pTargetAgent1 && "Hide target not assigned");
            m_vSteeringForce.PlusEqual(Hide(m_pTargetAgent1, m_pVehicle.World().Obstacles()).Mutiply(m_dWeightHide))
        End If

        If IsOn(behavior_type.follow_path) Then
            m_vSteeringForce.PlusEqual(FollowPath().Mutiply(m_dWeightFollowPath))
        End If

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -