如何建一个网站多少钱,wordpress 国外空间,wordpress欢迎主题,网站开发培训少儿类似鱼群#xff0c;鸟群这种群体运动模拟。 是Microscopic Models 微观模型#xff0c;定义每一个个体的行为#xff0c;然后合在一起。 主要是根据一定范围内族群其他对象的运动状态决定自己的运动状态
Cohesion
保证个体不会脱离群体 求物体一定半径范围内的其他临近物…类似鱼群鸟群这种群体运动模拟。 是Microscopic Models 微观模型定义每一个个体的行为然后合在一起。 主要是根据一定范围内族群其他对象的运动状态决定自己的运动状态
Cohesion
保证个体不会脱离群体 求物体一定半径范围内的其他临近物体的所有位置相加取平均位置,用这个位置进行一个追寻力seek
//求物体一定半径范围内的其他临近物体的所有位置用这个位置进行一个追寻力seek
Vec2 MoveNode::cohesion() {Vec2 averagePos Vec2::ZERO;int count 0;for (auto obj : _cohesionObj) {if (obj-getId() ! _id) {averagePos obj-getPosition();count;}}if (count 0) { averagePos * (1 / (float)count); return seek(averagePos) * _cohesionWeight;}return Vec2::ZERO;
}一定范围内的个体会自发的聚集在一起
separation
保证个体不会聚集太密 求物体一定半径范围内的其他临近物体的位置,用当前物体位置分别减去临近物体位置,获取单位方向向量乘以根据距离远近算出来的权重 越近权重越大。在把所有向量相加取平均值
Vec2 MoveNode::separation() {Vec2 steering Vec2::ZERO;int count 0;for (auto obj : _separationObj) {if (obj-getId() ! _id) {float dist this-getPosition().getDistance(obj-getPosition());Vec2 normalVector (this-getPosition() - obj-getPosition()).getNormalized();Vec2 desiredVelocity normalVector;desiredVelocity * (1 / dist);steering desiredVelocity;count;}}if (count 0) steering * (1 / (float)count);return steering * _dtSpeed * _separationWeight;
}一定范围内的个体会逐渐分散开来
alignment
保证个体的运动方向是跟随群体的 求物体一定半径范围内的其他临近物体的所有速度向量相加取平均值
Vec2 MoveNode::alignment() {Vec2 steering Vec2::ZERO;int count 0;for (auto obj : _alignmentObj) {if (obj-getId() ! _id) {steering obj-getVelocity();count;}}if (count 0) steering * (1 / (float)count);return steering * _alignmentWeight;
}可以看到一开始各自不同移动方向的个体在靠近群体的时候逐渐跟随上群体的方向
合并效果
给三种力分别设置不同的权重组合在一起可以对比群体运动的效果
node-setCohesionWeight(0.5);
node-setSeparationWeight(30);
node-setAlignmentWeight(0);对齐力权重为0即只有聚集力和分散力 集群只是聚成一团但并没有一个整体的运动方向
node-setCohesionWeight(0.5);
node-setSeparationWeight(0);
node-setAlignmentWeight(1);分散力权重为0即只有聚集力和对齐力 集群几乎直接聚集成同一个点进行移动
node-setCohesionWeight(0);
node-setSeparationWeight(30);
node-setAlignmentWeight(1);聚集力权重为0即只有分散力和对齐力 个体会随着周围的群体方向行进但是容易散开来
node-setCohesionWeight(0.5);
node-setSeparationWeight(30);
node-setAlignmentWeight(1);三种力都有的 可以通过对三种力设置不同的权重来控制集群的密集程度运动轨迹
我这里是简单粗暴的把所有物体加入遍历来筛选周围物体实际项目中需要各种优化如AOI等来减少遍历的个数
源码
CrowdSimulation.h
#ifndef __CROWD_SIMULATION_SCENE_H__
#define __CROWD_SIMULATION_SCENE_H__#include cocos2d.h
#include MoveNodeManager.h
USING_NS_CC;
using namespace std;class CrowdSimulationScene : public Scene
{
public:static Scene* createScene();virtual bool init();virtual bool onTouchBegan(Touch* touch, Event* unused_event);void setSeekPos(Vec2 seekPos);void setFleePos(Vec2 fleePos);void setWanderPos(Vec2 wanderPos);void showPursuitModel(Vec2 tarPos);void showCombineModel(Vec2 tarPos);void showCohsionModel();void showSeparationModel();void showAlignmentModel();void showCrowdModel();// implement the static create() method manuallyCREATE_FUNC(CrowdSimulationScene);void update(float dt);protected:EventListenerTouchOneByOne* _touchListener;Vec2 _touchBeganPosition;DrawNode* _mapDrawNode;DrawNode* _mapDrawNode1;MoveNodeManager* _manager;MoveNode* _moveNode;MoveNode* _moveNode1;vectorMoveNode* _fleeNodes;bool _isDrawMoveLine;
};#endifCrowdSimulation.cpp
#include CrowdSimulationScene.hScene* CrowdSimulationScene::createScene()
{return CrowdSimulationScene::create();
}static void problemLoading(const char* filename)
{printf(Error while loading: %s\n, filename);printf(Depending on how you compiled you might have to add Resources/ in front of filenames in CrowdSimulationScene.cpp\n);
}// on init you need to initialize your instance
bool CrowdSimulationScene::init()
{//// 1. super init firstif (!Scene::init()){return false;}auto visibleSize Director::getInstance()-getVisibleSize();Vec2 origin Director::getInstance()-getVisibleOrigin();auto layer LayerColor::create(Color4B(255, 255, 255, 255));layer:setContentSize(visibleSize);this-addChild(layer);_mapDrawNode DrawNode::create();this-addChild(_mapDrawNode);_mapDrawNode1 DrawNode::create();this-addChild(_mapDrawNode1);_touchListener EventListenerTouchOneByOne::create();_touchListener-setSwallowTouches(true);_touchListener-onTouchBegan CC_CALLBACK_2(CrowdSimulationScene::onTouchBegan, this);this-getEventDispatcher()-addEventListenerWithSceneGraphPriority(_touchListener, layer);_manager new MoveNodeManager();this-scheduleUpdate();return true;
}bool CrowdSimulationScene::onTouchBegan(Touch* touch, Event* event)
{_touchBeganPosition touch-getLocation();CCLOG(°∑ %f£¨ %f, _touchBeganPosition.x, _touchBeganPosition.y);// setSeekPos(_touchBeganPosition);//setFleePos(_touchBeganPosition);
// setWanderPos(_touchBeganPosition);
// showPursuitModel(_touchBeganPosition);
// showCombineModel(_touchBeganPosition);
// showCohsionModel();
// showSeparationModel();
// showAlignmentModel();showCrowdModel();return true;
}void CrowdSimulationScene::update(float dt) {if (_isDrawMoveLine _moveNode-getVelocity() ! Vec2::ZERO) _mapDrawNode-drawDot(_moveNode-getPosition(), 3, Color4F(0, 0, 0, 1));_mapDrawNode1-clear();for (auto e : _fleeNodes) {_mapDrawNode1-drawDot(e-getPosition(), 100, Color4F(1, 1, 0, 0.3));}
}void CrowdSimulationScene::setSeekPos(Vec2 seekPos) {if (_moveNode nullptr) {_moveNode _manager-getPlayer();_moveNode-setPos(Vec2(100, 100));this-addChild(_moveNode);_isDrawMoveLine true;}_moveNode-setTarPos(seekPos);_mapDrawNode-clear();_mapDrawNode-drawDot(seekPos, 150, Color4F(0, 1, 1, 0.3));_mapDrawNode-drawDot(seekPos, 10, Color4F(0, 1, 1, 1));
}void CrowdSimulationScene::setFleePos(Vec2 fleePos) {if (_moveNode nullptr) {_moveNode _manager-getPlayer();_moveNode-setPos(Vec2(100, 100));this-addChild(_moveNode);_isDrawMoveLine true;}_moveNode-setFleePos(_touchBeganPosition);_mapDrawNode-clear();_mapDrawNode-drawDot(_touchBeganPosition, 100, Color4F(0, 0, 1, 0.3));_mapDrawNode-drawDot(_touchBeganPosition, 10, Color4F(0, 0, 1, 1));
}void CrowdSimulationScene::setWanderPos(Vec2 wanderPos) {if (_moveNode nullptr) {_moveNode _manager-getWanderNode();this-addChild(_moveNode);}_moveNode-setWanderPos(wanderPos);_mapDrawNode-clear();_mapDrawNode-drawDot(wanderPos, 200, Color4F(1, 1, 0, 0.3));
}void CrowdSimulationScene::showPursuitModel(Vec2 tarPos){if (_moveNode nullptr) {_moveNode _manager-getPlayer();this-addChild(_moveNode);_moveNode1 _manager-getPursuitNode();this-addChild(_moveNode1);}_moveNode-setPos(Vec2(100, 100));_moveNode1-setPos(Vec2(100, 500));_moveNode1-switchPursuitObj(_moveNode);setSeekPos(tarPos);
}void CrowdSimulationScene::showCombineModel(Vec2 tarPos) {if (_moveNode nullptr) {_moveNode _manager-getPlayer();_moveNode-setPos(Vec2(100, 100));this-addChild(_moveNode);_isDrawMoveLine true;vectorVec2 wanderPos { Vec2(300, 300), Vec2(300, 600), Vec2(450,450),Vec2(600,640),Vec2(500,200),Vec2(650,400),Vec2(850,550) };for (auto v : wanderPos) {auto fleeNode _manager-getFleeNode();this-addChild(fleeNode);fleeNode-setWanderPos(v);_fleeNodes.push_back(fleeNode);_mapDrawNode1-drawDot(v, 100, Color4F(1, 1, 0, 0.3));}_moveNode-setFleeObjs(_fleeNodes);}setSeekPos(tarPos);
}void CrowdSimulationScene::showCohsionModel() {if (_manager-getFlockObjs().empty()) {for (int i 0; i 30; i) {auto cohesionObj _manager-getCohesionNode();this-addChild(cohesionObj);/*float x RandomHelper::random_realfloat(200, 1200);float y RandomHelper::random_realfloat(200, 500);cohesionObj-setPos(Vec2(x, y));*/}}auto objs _manager-getFlockObjs();for (auto obj : objs) {float x RandomHelper::random_realfloat(200, 1200);float y RandomHelper::random_realfloat(200, 500);obj-setPos(Vec2(x, y));}
}void CrowdSimulationScene::showSeparationModel() {if (_manager-getFlockObjs().empty()) {for (int i 0; i 30; i) {auto separationObj _manager-getSeparationNode();this-addChild(separationObj);/*float x RandomHelper::random_realfloat(650, 700);float y RandomHelper::random_realfloat(250, 300);separationObj-setPos(Vec2(x, y));*/}}auto objs _manager-getFlockObjs();for (auto obj : objs) {float x RandomHelper::random_realfloat(650, 700);float y RandomHelper::random_realfloat(250, 300);obj-setPos(Vec2(x, y));}
}void CrowdSimulationScene::showAlignmentModel() {if (_manager-getFlockObjs().empty()) {for (int i 0; i 30; i) {auto separationObj _manager-getAlignmentNode();this-addChild(separationObj);/*float x RandomHelper::random_realfloat(400, 800);float y RandomHelper::random_realfloat(200, 400);separationObj-setPos(Vec2(x, y));auto angle RandomHelper::random_realfloat(0, 360);float rad angle * M_PI / 180;float len 1;Vec2 v;v.x len * cos(rad);v.y len * sin(rad);separationObj-setVelocity(v);*/}}auto objs _manager-getFlockObjs();for (auto obj : objs) {float x RandomHelper::random_realfloat(100, 1300);float y RandomHelper::random_realfloat(100, 540);obj-setPos(Vec2(x, y));auto angle RandomHelper::random_realfloat(0, 360);float rad angle * M_PI / 180;float len 1;Vec2 v;v.x len * cos(rad);v.y len * sin(rad);obj-setVelocity(v);}
}void CrowdSimulationScene::showCrowdModel() {if (_manager-getFlockObjs().empty()) {for (int i 0; i 30; i) {auto flockNode _manager-getFlockNode();this-addChild(flockNode);/*float x RandomHelper::random_realfloat(100, 1300);float y RandomHelper::random_realfloat(100, 540);flockNode-setPos(Vec2(x, y));auto angle RandomHelper::random_realfloat(0, 360);float rad angle * M_PI / 180;float len 1;Vec2 v;v.x len * cos(rad);v.y len * sin(rad);flockNode-setVelocity(v);*/}}auto objs _manager-getFlockObjs();for (auto obj : objs) {float x RandomHelper::random_realfloat(100, 1300);float y RandomHelper::random_realfloat(100, 540);obj-setPos(Vec2(x, y));auto angle RandomHelper::random_realfloat(0, 360);float rad angle * M_PI / 180;float len 1;Vec2 v;v.x len * cos(rad);v.y len * sin(rad);obj-setVelocity(v);}
}MoveNodeManager.h
#ifndef __MOVE_NODE_MANAGER_H__
#define __MOVE_NODE_MANAGER_H__#include cocos2d.h
#include MoveNode.h
USING_NS_CC;
using namespace std;class MoveNodeManager
{
public:MoveNode* getPlayer();MoveNode* getWanderNode();MoveNode* getPursuitNode();MoveNode* getFleeNode();MoveNode* getCohesionNode();MoveNode* getSeparationNode();MoveNode* getAlignmentNode();MoveNode* getFlockNode();vectorMoveNode* getFlockObjs() { return _flockObjs; };protected:int _id 0;vectorMoveNode* _flockObjs;
};#endifMoveNodeManager.cpp
#include MoveNodeManager.hMoveNode* MoveNodeManager::getPlayer() {auto node MoveNode::create();node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 0, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 1, 1, 1));node-setSpeed(400);node-setMaxForce(20);node-setMass(10);node-setMaxSpeed(400);node-setTarSlowRadius(150);node-setFleeRadius(100);return node;
}MoveNode* MoveNodeManager::getWanderNode() {auto node MoveNode::create();node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 1, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 0, 1, 1));node-setSpeed(400);node-setMaxForce(20);node-setMass(20);node-setMaxSpeed(100);node-setCircleDistance(30);node-setCircleRadius(15);node-setChangeAngle(180);node-setWanderRadius(200);node-setWanderPullBackSteering(50);return node;
}MoveNode* MoveNodeManager::getPursuitNode() {auto node MoveNode::create();node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 1, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 0, 1, 1));node-setSpeed(400);node-setMaxForce(20);node-setMass(10);node-setMaxSpeed(400);return node;
}MoveNode* MoveNodeManager::getFleeNode() {auto node MoveNode::create();node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 1, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 0, 1, 1));node-setSpeed(400);node-setMaxForce(20);node-setMass(10);node-setMaxSpeed(50);node-setCircleDistance(30);node-setCircleRadius(15);node-setChangeAngle(180);node-setWanderRadius(200);node-setWanderPullBackSteering(50);return node;
}MoveNode* MoveNodeManager::getCohesionNode() {auto node MoveNode::create();_flockObjs.push_back(node);node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 0, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 1, 1, 1));node-setSpeed(300);node-setMaxForce(20);node-setMass(20);node-setMaxSpeed(50);node-setFleeRadius(50);node-setAllObj(_flockObjs);node-setCohesionRadius(100);return node;
}MoveNode* MoveNodeManager::getSeparationNode() {auto node MoveNode::create();_flockObjs.push_back(node);node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 0, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 1, 1, 1));node-setSpeed(300);node-setMaxForce(20);node-setMass(20);node-setMaxSpeed(50);node-setFleeRadius(50);node-setAllObj(_flockObjs);node-setSeparationRadius(30);return node;
}MoveNode* MoveNodeManager::getAlignmentNode() {auto node MoveNode::create();_flockObjs.push_back(node);node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 0, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 1, 1, 1));node-setSpeed(300);node-setMaxForce(20);node-setMass(20);node-setMaxSpeed(150);node-setFleeRadius(50);node-setAllObj(_flockObjs);node-setAlignmentRadius(150);return node;
}MoveNode* MoveNodeManager::getFlockNode() {auto node MoveNode::create();_flockObjs.push_back(node);node-setId(_id);_id;auto body DrawNode::create();node-addChild(body);body-drawDot(Vec2(0, 0), 10, Color4F(0, 0, 0, 1));auto direct DrawNode::create();node-addChild(direct);node-setDirect(direct);direct-drawDot(Vec2(0, 0), 3, Color4F(1, 1, 1, 1));node-setSpeed(300);node-setMaxForce(20);node-setMass(20);node-setMaxSpeed(100);node-setFleeRadius(50);node-setAllObj(_flockObjs);node-setCohesionRadius(100);node-setSeparationRadius(40);node-setAlignmentRadius(50);node-setCohesionWeight(0.5);node-setSeparationWeight(30);node-setAlignmentWeight(1);return node;
}MoveNode.h
#ifndef __MOVE_NODE_H__
#define __MOVE_NODE_H__#include cocos2d.h
USING_NS_CC;
using namespace std;class MoveNode : public Node
{
public:static MoveNode* create();CC_CONSTRUCTOR_ACCESS:virtual bool init() override;void setId(int id) { _id id; };void setDirect(DrawNode* direct) { _direct direct; };void setSpeed(float speed) { _speed speed; };void setMaxForce(float maxForce) { _maxForce maxForce; };void setMass(float mass) { _mass mass; };void setMaxSpeed(float maxSpeed) { _maxSpeed maxSpeed; };void setTarSlowRadius(float tarSlowRadius) { _tarSlowRadius tarSlowRadius; };void setFleeRadius(float fleeRadius) { _fleeRadius fleeRadius; };void setCircleDistance(float circleDistance) { _circleDistance circleDistance; };void setCircleRadius(float circleRadius) { _circleRadius circleRadius; };void setChangeAngle(float changeAngle) { _changeAngle changeAngle; };void setWanderRadius(float wanderRadius) { _wanderRadius wanderRadius; };void setWanderPullBackSteering(float wanderPullBackSteering) { _wanderPullBackSteering wanderPullBackSteering; };void setPos(Vec2 pos);void setTarPos(Vec2 tarPos) { _tarPos tarPos; };void setFleePos(Vec2 fleePos) { _fleePos fleePos; };void setFleeObjs(vectorMoveNode* fleeObjs) { _fleeObjs fleeObjs; };void setWanderPos(Vec2 wanderPos);void switchPursuitObj(MoveNode* pursuitObj);void setAllObj(vectorMoveNode** allObj) { _allObj allObj; };void setCohesionRadius(float cohesionRadius) { _cohesionRadius cohesionRadius; };void setSeparationRadius(float separationRadius) { _separationRadius separationRadius; };void setAlignmentRadius(float alignmentRadius) { _alignmentRadius alignmentRadius; };void setCohesionWeight(float cohesionWeight) { _cohesionWeight cohesionWeight; };void setSeparationWeight(float separationWeight) { _separationWeight separationWeight; };void setAlignmentWeight(float alignmentWeight) { _alignmentWeight alignmentWeight; };Vec2 seek(Vec2 seekPos);Vec2 flee();Vec2 wander();Vec2 pursuit();Vec2 cohesion();Vec2 separation();Vec2 alignment();Vec2 wallAvoid();Vec2 turncate(Vec2 vector, float maxNumber);Vec2 changeAngle(Vec2 vector, float angle);void updatePos();void update(float dt);void findNeighbourObjs();int getId() { return _id; };Vec2 getVelocity(){ return _velocity; };void setVelocity(Vec2 velocity) { _velocity velocity; };
protected:DrawNode* _direct;int _id;float _speed; //速度float _maxForce; //最大转向力即最大加速度float _mass; //质量float _maxSpeed; //最大速度float _tarSlowRadius; //抵达目标减速半径float _fleeRadius; //逃离目标范围半径float _circleDistance; //巡逻前方圆点距离float _circleRadius; //巡逻前方圆半径float _changeAngle; //巡逻转向最大角度float _wanderRadius; //巡逻点范围半径float _wanderPullBackSteering; //超出巡逻范围拉回力float _alignmentRadius; //方向对齐判断的范围半径float _cohesionRadius; //聚集判断的范围半径float _separationRadius; //分离判断得范围半径float _alignmentWeight 1.0f; //方向对齐力权重float _cohesionWeight 1.0f; //聚集力权重float _separationWeight 1.0f; //分离力权重float _dtSpeed; //每帧速度值Vec2 _velocity; //速度float _wanderAngle; //巡逻角度Vec2 _wanderPos; //巡逻范围中心点Vec2 _tarPos; //目标点Vec2 _fleePos; //逃离点MoveNode* _pursuitObj; //追逐目标vectorMoveNode* _fleeObjs; //逃离目标vectorMoveNode** _allObj; //所有对象vectorMoveNode* _alignmentObj; //方向对齐目标vectorMoveNode* _cohesionObj; //聚集目标vectorMoveNode* _separationObj; //分离目标float wallAvoidRadius 50.0f; //墙壁碰撞检测半径
};#endifMoveNode.cpp
#include MoveNode.hbool MoveSmooth true;MoveNode* MoveNode::create() {MoveNode* moveNode new(nothrow) MoveNode();if (moveNode moveNode-init()) {moveNode-autorelease();return moveNode;}CC_SAFE_DELETE(moveNode);return nullptr;
}bool MoveNode::init()
{_tarPos Vec2(-1, -1);_wanderPos Vec2(-1, -1);_velocity.setZero();_pursuitObj nullptr;this-scheduleUpdate();return true;
}void MoveNode::update(float dt)
{findNeighbourObjs();_dtSpeed _speed * dt;if (MoveSmooth) {Vec2 steering Vec2::ZERO;steering seek(_tarPos);steering flee();steering wander();steering pursuit();steering cohesion();steering separation();steering alignment();steering turncate(steering, _maxForce);steering * ( 1 / (float)_mass );_velocity steering;}else {_velocity seek(_tarPos);_velocity flee();_velocity wander();_velocity pursuit();_velocity cohesion();_velocity separation();_velocity alignment();}_velocity wallAvoid();_velocity turncate(_velocity, _maxSpeed * dt);updatePos();
}Vec2 MoveNode::wallAvoid() {Vec2 temp _velocity.getNormalized();temp * wallAvoidRadius;Vec2 tarPos this-getPosition() temp;if (!Rect(Vec2::ZERO, Director::getInstance()-getVisibleSize()).containsPoint(tarPos)) {Vec2 steering Vec2::ZERO;if (tarPos.y Director::getInstance()-getVisibleSize().height) steering Vec2(0, -1);if (tarPos.y 0) steering Vec2(0, 1);if (tarPos.x Director::getInstance()-getVisibleSize().width) steering Vec2(-1, 0);if (tarPos.x 0) steering Vec2(1, 0);return steering * _dtSpeed;}return Vec2::ZERO;
}void MoveNode::updatePos() {Vec2 tarPos this-getPosition() _velocity;if (!Rect(Vec2::ZERO, Director::getInstance()-getVisibleSize()).containsPoint(tarPos)) {_velocity _velocity * -100;}Vec2 directPos _velocity.getNormalized() * 5;_direct-setPosition(directPos);this-setPosition(tarPos);if (_velocity Vec2::ZERO) _tarPos Vec2(-1, -1);
}Vec2 MoveNode::turncate(Vec2 vector, float maxNumber) {if (vector.getLength() maxNumber) { vector.normalize();vector * maxNumber;}return vector;
}//追逐转向力
Vec2 MoveNode::seek(Vec2 seekPos){if (seekPos Vec2(-1, -1)) return Vec2::ZERO;Vec2 normalVector (seekPos - this-getPosition()).getNormalized();float dist this-getPosition().getDistance(seekPos);Vec2 desiredVelocity normalVector * _dtSpeed;//靠近目标减速带if (dist _tarSlowRadius) desiredVelocity * (dist / _tarSlowRadius);Vec2 steering;if (MoveSmooth) steering desiredVelocity - _velocity;else steering desiredVelocity;return steering;
}//躲避转向力
Vec2 MoveNode::flee() {Vec2 steering Vec2::ZERO;if (!_fleeObjs.empty()) {for (auto eludeObj : _fleeObjs) {auto fleePos eludeObj-getPosition();if (fleePos.getDistance(this-getPosition()) _fleeRadius) {Vec2 normalVector (this-getPosition() - fleePos).getNormalized();Vec2 desiredVelocity normalVector * _dtSpeed;Vec2 steeringChild;if (MoveSmooth) steeringChild desiredVelocity - _velocity;else steeringChild desiredVelocity;steering steeringChild;}}return steering;}if(_fleePos Vec2::ZERO) return steering;if (this-getPosition().getDistance(_fleePos) _fleeRadius) {Vec2 normalVector (this-getPosition() - _fleePos).getNormalized();Vec2 desiredVelocity normalVector * _dtSpeed;if (MoveSmooth) steering desiredVelocity - _velocity;else steering desiredVelocity;}return steering;
}Vec2 MoveNode::changeAngle(Vec2 vector, float angle) {float rad angle * M_PI / 180;float len vector.getLength();Vec2 v;v.x len * cos(rad);v.y len * sin(rad);return v;
}Vec2 MoveNode::wander() {if (_wanderPos Vec2(-1, -1)) return Vec2::ZERO;Vec2 circleCenter _velocity.getNormalized();circleCenter * _circleDistance;Vec2 displacement Vec2(0, -1);displacement * _circleRadius;displacement changeAngle(displacement, _wanderAngle);float randomValue RandomHelper::random_realfloat(-0.5f, 0.5f);_wanderAngle _wanderAngle randomValue * _changeAngle;Vec2 wanderForce circleCenter - displacement;float dist this-getPosition().getDistance(_wanderPos);if (dist _wanderRadius) {// 偏离漫游点一定范围的话给个回头力Vec2 desiredVelocity (_wanderPos - this-getPosition()).getNormalized() * _wanderPullBackSteering;desiredVelocity - _velocity;wanderForce desiredVelocity;}return wanderForce;
}Vec2 MoveNode::pursuit() {if (_pursuitObj nullptr) return Vec2::ZERO;Vec2 pursuitPos _pursuitObj-getPosition();float t this-getPosition().getDistance(pursuitPos) / _dtSpeed;//float t 3;
// Vec2 tarPos pursuitPos _pursuitObj-getVelocity() * t;Vec2 tarPos pursuitPos;return seek(tarPos);
}//求物体一定半径范围内的其他临近物体的所有位置用这个位置进行一个追寻力seek
Vec2 MoveNode::cohesion() {Vec2 averagePos Vec2::ZERO;int count 0;for (auto obj : _cohesionObj) {if (obj-getId() ! _id) {averagePos obj-getPosition();count;}}if (count 0) { averagePos * (1 / (float)count); return seek(averagePos) * _cohesionWeight;}return Vec2::ZERO;
}//求物体一定半径范围内的其他临近物体的位置,用当前物体位置分别减去临近物体位置,获取单位方向向量乘以根据距离远近算出来得权重
//越近权重越大。在把所有向量相加取平均值
Vec2 MoveNode::separation() {Vec2 steering Vec2::ZERO;int count 0;for (auto obj : _separationObj) {if (obj-getId() ! _id) {float dist this-getPosition().getDistance(obj-getPosition());Vec2 normalVector (this-getPosition() - obj-getPosition()).getNormalized();Vec2 desiredVelocity normalVector;desiredVelocity * (1 / dist);steering desiredVelocity;count;}}if (count 0) steering * (1 / (float)count);return steering * _dtSpeed * _separationWeight;
}//求物体一定半径范围内的其他临近物体的所有速度向量相加取平均值
Vec2 MoveNode::alignment() {Vec2 steering Vec2::ZERO;int count 0;for (auto obj : _alignmentObj) {if (obj-getId() ! _id) {steering obj-getVelocity();count;}}if (count 0) steering * (1 / (float)count);return steering * _alignmentWeight;
}void MoveNode::setPos(Vec2 pos) {this-setPosition(pos);_velocity.setZero();
}void MoveNode::setWanderPos(Vec2 wanderPos) {_wanderPos wanderPos;setPos(wanderPos);
}void MoveNode::switchPursuitObj(MoveNode* pursuitObj) {if (_pursuitObj nullptr) _pursuitObj pursuitObj;else {_pursuitObj nullptr;_velocity Vec2::ZERO;_tarPos Vec2(-1, -1);}
}void MoveNode::findNeighbourObjs() {if (_allObj nullptr) return;_alignmentObj.clear();_cohesionObj.clear();_separationObj.clear();for (auto obj : *_allObj) {float dist this-getPosition().getDistance(obj-getPosition());if (dist _alignmentRadius) {_alignmentObj.push_back(obj);}if (dist _cohesionRadius) {_cohesionObj.push_back(obj);}if (dist _separationRadius) {_separationObj.push_back(obj);}}
}