Game underlying logic, motion && pathfinding (iii)

Source: Internet
Author: User

In the previous article we explained several basic control forces, and today we will discuss several more complex behaviors involving collisions and auxiliary graphics for motion control.

7. WanderWandering (patrolling)

Wandering (patrolling) is a very common behavior, but it is not particularly easy to get smoothly smooth steering behavior, there is a smooth move that borrows the aid circle implementation.

, we construct an auxiliary circle in front of the object, we control the target point, and then use the Seek method to control the motion behavior, if we let the target point in the circle motion, can produce a force, he has the following properties:

    • Must forward (force the direction of the object's current motion)
    • One-frame corner range is the angle of the tangent to the x-axis
    • Size is the range of circles and x-axis intersections

So we can control the relative position of the auxiliary circle to control the wander behavior, for example, we want the total motion trajectory to be an irregular circle, we can put the circle in the first quadrant (counterclockwise rotation) or the fourth quadrant (clockwise rotation), the circle position is max_double, The line motion is performed.

The next thing we need to do is to write a method of randomly moving the target point around the circumference (which can be written casually, for example, with trigonometric functions), here's an implementation:

    • Random movement within a certain range of target points
    • Projecting it onto a circle (gets its unit vector)

We first add a new member variable for the steeringbehaviors class:

//wander attributes    Vec2 _wanderTarget;//目标点    double _wanderRadius;//辅助圆半径    double _wanderDistance;//辅助圆离物体的距离    double _wanderJitter;//给目标点的随机位置一个限制值,这是为了减少速度变化过快产生的抖动

Next is the implementation of the wander function:

VEC2 steeringbehaviors:: Wander(){//random Move_wandertarget=VEC2 (Random:: Rand(-1,1)*_wanderjitter, Random:: Rand(-1,1)*_wanderjitter);//project it onto the circle_wandertarget=_wandertarget.Getnormalized ()*_wanderradius;//add jitterVEC2 targetonlocal=_wandertarget+VEC2 (_wanderjitter,0);//we use Sprite instead of entity itself    if(_ownervehicle -Getsprite () -GetPosition ()!=_ownervehicle -Position ()) {_ownervehicle -Getsprite () -SetPosition (_ownervehicle -Position ()); } Vec2 Targetonworld=_ownervehicle -Getsprite () -Converttoworldspacear (targetonlocal);returnTargetonworld-_ownervehicle -Position ();}
Thinking

Wander method describes a way to reverse the algorithm, we can imagine the situation of object motion, want to get a smooth non-jitter motion, is to limit the movement direction and size changes, here are a few features:
1, must forward
2, direction changes have a certain trend, in a period of time always in a direction of turning
Knowing these two points can deal with this problem: the control force must be synthesized by two forces, one of which is bound towards the direction of the object's motion (condition one)
Another force controls the direction of the turn, we only need to record the direction of the previous force (where the position of the target point is recorded), on this basis change (condition two)
There is also a way to control the direction of the turn is the greater the change of force, the smaller the use of the circle here, of course, we can be a straight line (slope is negative)
As a result, there can be a lot of auxiliary graphics here, the target point of control can also have a lot of solutions, of course, after a lot of data testing, adjustment parameters are also essential

8. obstacleavoidanceAvoid obstacles

The next algorithm may encounter the concept of obstacle terrain entity, in our implementation, the class inherits the BaseEntity class, temporarily used only boudingbox Collision Box This property. , we will have the opportunity to introduce several basic game implementations in detail later.

Algorithm, let's first imagine the human condition of avoiding obstacles (psychological monologue ^_^||| ):

"What's the weather like doing at night?" "
"In front of the pole, be careful not to hit it." ”

Oh, a little unreasonable, but it contains a very important information, "Front is the Telegraph pole", the human use of vision to perceive the existence of obstacles, we will not add visual elements to the game entities, but we here by the auxiliary rectangle to implement the concept of vision .

, the triangular object is the moving entity, the two vertical line is the local coordinate system axis, the rectangle is the auxiliary rectangle, the gray circle is the obstacle collision box, the outer circle is the estimation circle (detects the collision in advance).
Predicting the existence of a circle is like humans don't move with obstacles.

We traverse all the obstacleto find out which of the following features are met:

    • Intersect with auxiliary rectangle (with overlapping area)
    • The center is in front of the object
    • Estimated circle intersection with object X axis
compute intersections (repulsion points)

This approach is implemented in a few steps:
1. Find all obstructions in the circle range that detects the radius of the auxiliary rectangular length

STD:: vector<BaseEntity*>Entitymanenger::getneighbors (baseentity* centreentity,STD:: vector<BaseEntity*>Entitylist,DoubleRADIUS) {STD:: vector<BaseEntity*>Vec        For_each (Entitylist.cbegin (), Entitylist.cend (), [&radius,centreentity,&vec] (baseentity* neighborEntity) {        VEC2 dis = neighborentity->position ()-centreentity->position (); Radius + =0.5*max (Neighborentity->getsprite ()->getboundingbox (). Size.Height, Neighborentity->getsprite ()->getBou Ndingbox (). Size.width);if(Centreentity! = NEIGHBORENTITY&AMP;&AMP;DIS.GETLENGTHSQ () < Radius*radius)        {Vec.push_back (neighborentity); }    }    );returnVEC;}

2. Transfer the filtered Obs to the object's local coordinate system
3. Exclude Obs with negative x
4, excluding the Y value is greater than the estimated circle radius (excluding the x-axis does not intersect)

After filtering out the Intersect obs , we need to find the nearest intersection with the x-axis, which is where the most repulsive force is applied, and the repulsion of the other intersections is omitted.
5. Find the nearest intersection
Let's take a look at the first five steps of the code:
New member variables:

double _dBoxLenth;
VEC2 Steeringbehaviors::obstacleavoidance (Const STD:: vector<BaseEntity*>& obstacles) {_dboxlenth = mindetectionboxlength* (1+ _ownervehicle->speed ()/_ownervehicle->maxspeed ());//nearest intersection dis alone axis x    Doubleniol_x = max_double;//nearest intersection position on localVEC2 Niol_po = Vec2::zero;//nearest Obstaclebaseentity* nobstacle = NULL;//entities within view range    STD:: vector<BaseEntity*>Neighborobstacles = Emgr->getneighbors (_ownervehicle, Emgr->getvecbytype (1), _dboxlenth);//find The point of theFor_each (Neighborobstacles.begin (), Neighborobstacles.end (), [ This, &niol_x,&niol_po,&nobstacle] (baseentity* obstacle) {Vec2 poonlocal = _ownervehicle->getsprite () ->converttonodespacear (Obstacle->position ());//tips:better to use the "do while (0)" struct        if(Poonlocal.x >=0)        {DoubleExpandedradius = Obstacle->getboundingradius () + _ownervehicle->getboundingradius ();if(fabs(POONLOCAL.Y) < Expandedradius) {//find out the intersections                DoubleIntersectionx = poonlocal.x-(Expandedradius*expandedradius-(POONLOCAL.Y) * (POONLOCAL.Y));//just determined by the positive axis X                if(Intersectionx <=0) {Intersectionx = poonlocal.x + (Expandedradius*expandedradius-(POONLOCAL.Y) * (Poonlo                CAL.Y)); }if(Intersectionx < niol_x)                    {niol_x = Intersectionx;                    Niol_po = poonlocal;                Nobstacle = obstacle; }            }        }    }    );//to Be Continued

A few points have been forgotten to declare:
1. The length of the auxiliary rectangle is positively correlated with the object's current velocity.
2, the calculation with a sprite to assist the calculation of the local coordinate system, because in this game that the entity's coordinate system property is identical to its sprite (update the spritewhile updating the entity), the reason the entity does not inherit The Sprite class is because there are a lot of bugs and it is not recommended to use inheritance
3, estimated radius of the circle =Obs radius + Auxiliary Box width/2 ( we approximate to the object radius )

Calculate the control force

With the repulsion point, we can easily calculate the control force, the classic processing is as follows:

Divided into two forces: braking forces parallel to the x-axis, repulsion at the repulsion point along the obs Normal

Approximate processing here, convenient calculation, the repulsion is treated as the force of the y-axis

The magnitude of these two forces is inversely proportional to the x-axis distance between the Obs and the entity

Look directly at the code:

//go on//is obstacle exist    if(nobstacle) {//no matter on the X or Y, the closer, the stronger the for shouble be        //the effect on xDouble multiplier= 1.0 +(_dboxlenth-Niol_po.X/_dboxlenth;//the effect on ySteeringforce.Y=(nobstacle -Getboundingradius ()-Niol_po.Y*Multiplier//apply a braking forceSteeringforce.X=(nobstacle -Getboundingradius ()-Niol_po.X*Brakingweight; }//convert The force from local to world space    return_ownervehicle -Getsprite () -Converttoworldspacear (Steeringforce);}

Finally, don't forget to convert to world coordinate system

Let's talk about it today, we'll continue next time.

Ready to write a lengthy blog about the game's underlying algorithms, physical algorithms, and AI (which focuses on machine learning in-game applications), Welcome to ╰ ( ̄▽ ̄) ╯

Game underlying logic, motion && pathfinding (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.