S013010C_Aaron_Smith_Tank::S013010C_Aaron_Smith_Tank(SDL_Renderer* renderer, TankSetupDetails details,bool demoTank)
	: BaseTank(renderer, details)
{
	mTankTurnDirection = DIRECTION_UNKNOWN;
	mTankTurnKeyDown = false;
	mTankMoveDirection = DIRECTION_NONE;
	mTankMoveKeyDown = false;
	mManTurnDirection = DIRECTION_UNKNOWN;
	mManKeyDown = false;
	mFireKeyDown = false;
	mIsSeeking = false;
	mSteering = new S013010C_Aaron_Smith_Steering(this,demoTank);
	mTargetPos = Vector2D(0, 0);//Vector2D(479.5f,100.0f);
	

	mTargetSprite = new Texture2D(renderer);
	mTargetSprite->LoadFromFile("Images\\Target.png");
	mDrawTarget = false;
	mHasTarget = false;
	mRenderer = renderer;
	mIsTestTank = demoTank;

	mShowingDebug = false;
	mLeftFeelers = vector<Vector2D>();
	mRightFeelers = vector<Vector2D>();
	mStraightFeelers = vector<Vector2D>();
	mLeftSideFeelers = vector<Vector2D>();
	mRightSideFeelers = vector<Vector2D>();
	/*CreateLeftFeelers(mLeftFeelers);
	CreateRightFeelers(mRightFeelers);
	CreateStraightFeelers(mStraightFeelers);*/
	CreateFeelers(mRightSideFeelers, 90,	60, GetCentralPosition());
	CreateFeelers(mLeftSideFeelers, -90,	60, GetCentralPosition());
	CreateFeelers(mLeftFeelers,		-30,	80, mTopLeftCorner);
	CreateFeelers(mRightFeelers,	 30,	80, mTopRightCorner);
	CreateFeelers(mStraightFeelers,  0,		70, mTopLeftCorner);


	demoPursuit = false;
	cout << "1. Arrive" << endl;
	cout << "2. Seek" << endl;
	cout << "3. Flee" << endl;
	cout << "4. Pursuit" << endl;
}
Vec2 SteeringForce::WallAvoidance(const std::vector<Wall2D> &walls)
{
    //创建实体的触须
    CreateFeelers();
    
    double DistToThisIp = 0.0;
    double DistToClosestIp = MAXFLOAT;
    
    //保存walls的向量的索引
    int ClosestWall = -1;
    
    Vec2    SteeringForce,
            point,
            ClosestPoint;
    
    float s,t;
    
    //逐个检查每条触须
    for (int flr = 0; flr<m_feelers.size(); ++flr) {
        
        //跑过每堵墙,检查相交点
        for (int w = 0;w<walls.size() ; w++ ) {
            if (Vec2::isLineIntersect(walls[w].From ,walls[w].To ,m_feelers[flr],m_pVehicle->getPosition() ,&s,&t)) {
                
                if (s <1&&t<1&&s>0&&t>0) {
                    ClosestPoint = m_pVehicle->getPosition() + t*(m_feelers[flr] - m_pVehicle->getPosition());
                    DistToThisIp = (ClosestPoint).length();
                    
                    
                    if (DistToThisIp < DistToClosestIp) {
                        DistToClosestIp = DistToThisIp;
                        ClosestWall = w;
                        ClosestPoint = point;
                    }
                }
                
            }
        }//下一堵墙
        
        if (ClosestWall >=0) {
            Vec2 OverShoot = m_feelers[flr]-ClosestPoint;
            SteeringForce = walls[ClosestWall].Normal*OverShoot.length();
        }
    }//下一跳触须
    
    
    
    return SteeringForce;
}
Example #3
0
ofVec3f SteeringBehaviors::WallAvoidance(const std::vector<Wall*>& _walls)
{
	CreateFeelers();
	float DistToThisIP = 0.0;
	float DistToClosestIP = FLT_MAX;

	int ClosestWall = -1;

	ofVec3f _steeringForce,
		point,
		ClosestPoint;

	ofVec3f vpos = m_Vehicle->Pos(); // alias

	ofxIntersection _ofxIntersection;
	IsLine linedFeeler;
	IsPlane planedWall;

	//examine feelers
	for (unsigned int flr = 0; flr < m_Feelers.size(); ++flr)
	{
		linedFeeler.set(vpos, *m_Feelers[flr]);
		//linedFeeler.draw();
		//examine walls
		for (unsigned int w = 0; w < _walls.size(); ++w)
		{
			switch (_walls[w]->EntityType())
			{
			case BaseEntity::wallxz:
				planedWall.set(_walls[w]->Pos(), _walls[w]->GetYAxis());
				break;
			case BaseEntity::wallyz:
				planedWall.set(_walls[w]->Pos(), _walls[w]->GetXAxis());
				break;
			case BaseEntity::wallyx:
				planedWall.set(_walls[w]->Pos(), _walls[w]->GetZAxis());
				break;
			}
			IntersectionData Id = _ofxIntersection.LinePlaneIntersection(linedFeeler, planedWall);
			if (Id.isIntersection)
			{
				DistToThisIP = m_Vehicle->Pos().distance(Id.pos);
				if (DistToThisIP < DistToClosestIP)
				{
					DistToClosestIP = DistToThisIP;
					ClosestWall = w;
					ClosestPoint = Id.pos;
				}
				break;
			}
		}//next wall
		
		 //if wall found return force
		if (ClosestWall >= 0)
		{
			ofVec3f OverShoot = *m_Feelers[flr] - ClosestPoint;
			int _sign = 1;
			//create a force in the direction of the wall normal, with a 
			//magnitude of the overshoot
			
			switch (_walls[ClosestWall]->EntityType())
			{
				case BaseEntity::wallxz:
					if (vpos.y > ClosestPoint.y)
						_sign = 1;
					else
						_sign = -1;
					_steeringForce = _walls[ClosestWall]->GetYAxis()*OverShoot.length()*_sign;
					break;
				case BaseEntity::wallyx:
					if (vpos.z > ClosestPoint.z)
						_sign = 1;
					else
						_sign = -1;
					_steeringForce = _walls[ClosestWall]->GetZAxis()*OverShoot.length()*_sign;
					break;
				case BaseEntity::wallyz:
					if (vpos.x > ClosestPoint.x)
						_sign = 1;
					else
						_sign = -1;
					_steeringForce = _walls[ClosestWall]->GetXAxis()*OverShoot.length()*_sign;
					break;
			}
		}
	
	}//next feeler

	DestroyFeelers();
	return  (_steeringForce);// -m_Vehicle->Velocity());

}
Vector2D B020612E_Steering::ObstacleAvoidance(const std::vector<GameObject*>& obstacles)
{
	CreateFeelers();

	return Vector2D(0.0f, 0.0f);
}
void S013010C_Aaron_Smith_Tank::MoveInHeadingDirection(float deltaTime)
{
	
	mSteeringForce = mSteering->Calculate(deltaTime);
	//Acceleration = Force/Mass
	//mSteeringForce.Truncate(GetMaxForce());
	Vector2D acceleration = mSteeringForce / GetMass();
	
	//Update velocity.
	mVelocity += acceleration * deltaTime;

	//Don't allow the tank does not go faster than max speed.
	mVelocity.Truncate(GetMaxSpeed());
	//cout << "mVelocity " << mVelocity.x << ":" << mVelocity.y << endl;
	//cout << "VELOCITY " << mVelocity.Length() << endl;

	
	if (mVelocity.Length() > 0.0001)
	{
		if (mVelocity.x != mVelocity.x || mVelocity.y != mVelocity.y) return;
		Vector2D newPosition = GetPosition();
		newPosition.x += mVelocity.x*deltaTime;
		newPosition.y += (mVelocity.y)*deltaTime;	//Y flipped as adding to Y moves down screen.
		SetPosition(newPosition);

		Vector2D ahead = Vec2DNormalize(mVelocity);
		if (ahead.Length() == 0)
			ahead = mHeading;

		Vector2D cenPos = GetCentrePosition();
		Vector2D aheadDistance = cenPos + ahead * 10 ;
		
		RotateHeadingToTarget(aheadDistance);

	//	double dynamicLength = mVelocity.Length() / GetMaxSpeed();
		

		Vector2D left = (mHeading - mSide) * 0.5;
		Vector2D right = (mHeading + mSide) * 0.5;

		mTopLeftCorner.x = left.x;
		mTopLeftCorner.y = left.y;
		mTopLeftCorner = Vec2DNormalize(mTopLeftCorner) * -10;
		mTopLeftCorner += GetCentralPosition();

		mTopRightCorner.x = right.x;
		mTopRightCorner.y = right.y;
		mTopRightCorner = Vec2DNormalize(mTopRightCorner) * -10;
		mTopRightCorner += GetCentralPosition();



		/*double angle = 70;
		int ahead2Amount = 40;
		int ahead1Amount = ahead2Amount / 2;
		int side2Amount = 30;
		int side1Amount = side2Amount / 2;

		Vector2D fannedLeftAhead;
		fannedLeftAhead.x = ahead.x * cos(DegsToRads(-angle)) - ahead.y * sin(DegsToRads(-angle));
		fannedLeftAhead.y = ahead.x * sin(DegsToRads(-angle)) + ahead.y * cos(DegsToRads(-angle));
		Vector2D fannedRightAhead;
		fannedRightAhead.x = ahead.x * cos(DegsToRads(angle)) - ahead.y * sin(DegsToRads(angle));
		fannedRightAhead.y = ahead.x * sin(DegsToRads(angle)) + ahead.y * cos(DegsToRads(angle));

		mLeftAhead2Distance = (mTopLeftCorner) + (fannedLeftAhead *  dynamicLength * side2Amount);
		mLeftAhead1Distance = (mTopLeftCorner) + (fannedLeftAhead *  dynamicLength * side1Amount);
		
		mRightAhead2Distance = (mTopRightCorner)+(fannedRightAhead  *  dynamicLength * side2Amount);
		mRightAhead1Distance = (mTopRightCorner)+(fannedRightAhead  *  dynamicLength * side1Amount);

		mAhead1Distance = GetCentrePosition() + (ahead * dynamicLength * ahead1Amount );
		mAhead2Distance = GetCentrePosition() + (ahead * dynamicLength * (ahead2Amount + 50));*/
		//cout << "AHEAD " << mLeftAhead2Distance.x << ":" << mLeftAhead2Distance.y << endl;
		//mAhead1Distance = mAhead2Distance * 0.5;
	}

	CreateFeelers(mRightSideFeelers, 90, 30, GetCentralPosition());
	CreateFeelers(mLeftSideFeelers, -90, 30, GetCentralPosition());
	CreateFeelers(mLeftFeelers, -40, 30, mTopLeftCorner);
	CreateFeelers(mRightFeelers, 40, 30, mTopRightCorner); // 70
	CreateFeelers(mStraightFeelers, 0, 40, mTopLeftCorner);
}