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; }
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); }