void CurrencyOrb::DoTrackPlayer(float delta) { mSineWaveProps.DoSineWave = false; Player * player = GameObjectManager::Instance()->GetPlayer(); if (!player) { return; } // accelerate towards the target Vector3 direction = Vector3(player->CollisionCentreX(), player->CollisionCentreY(), player->Z()) - m_position; direction.Normalise(); m_direction = direction; float multiplier = mTimeTracking > 2.0f ? 3.0f : 1.0f; bool prioritiseX = false; if (std::abs(m_direction.X) > std::abs(m_direction.Y)) { AccelerateX(m_direction.X, kAccelerateRate * multiplier); prioritiseX = true; } else { AccelerateY(m_direction.Y, kAccelerateRate * multiplier); } if (prioritiseX && ((m_direction.X < 0 && m_velocity.X > 0) || (m_direction.X > 0 && m_velocity.X < 0))) { // the velocity of the orb is still moving in the opposite x direction // let's give it a helping hand to catch up by accelerating harshly AccelerateX(m_direction.X, kHarshAccelerateRate * multiplier); } if (!prioritiseX && ((m_direction.Y < 0 && m_velocity.Y > 0) || (m_direction.Y > 0 && m_velocity.Y < 0))) { // the velocity of the orb is still moving in the opposite y direction // let's give it a helping hand to catch up by accelerating harshly AccelerateY(m_direction.Y, kHarshAccelerateRate * multiplier); } Vector2 dir = Vector2(m_velocity.X, m_velocity.Y); dir.Normalise(); if (dir.X > 0) { SetRotationAngle(-acos(dir.Dot(Vector2(0, -1)))); } else { SetRotationAngle(acos(dir.Dot(Vector2(0, -1)))); } }
//\=============================================================================================================================== //\ Distance to a wall with a counter clockwise rotated normal //\=============================================================================================================================== float Vector2::DistToWallCCWNormal(const Vector2& start, const Vector2& end) const { Vector2 p = start - end; p.Normalise(); Vector2 n = p.PerpCCW(); Vector2 q = *this - start; float d = DotProd(q, n); return d; }
Vector2 Vector2::WallCollisionCCWNormal(const Vector2& start, const Vector2& end, const Vector2& dir, const float& bounce) const { Vector2 p = start - end; p.Normalise(); Vector2 n = p.PerpCCW(); Vector2 q = *this - start; float d = DotProd(q, n); if (d < 0.f) { Vector2 v2 = dir - (1 + bounce) * (DotProd(dir, n) * n); v2.Normalise(); return v2; } return *this + dir; }
//Update method void GameMouse::Update(float) { //Get input and physics manager IND_Input* input = SingletonIndieLib::Instance()->Input; #ifdef _DEBUGGING if(input->OnMouseButtonPress(IND_MBUTTON_WHEELUP )) { Camera2DPointer camera = SingletonIndieLib::Instance()->GetCamera("General"); camera->Zoom(true); } if(input->OnMouseButtonPress(IND_MBUTTON_WHEELDOWN )) { Camera2DPointer camera = SingletonIndieLib::Instance()->GetCamera("General"); camera->Zoom(false); } #endif //Update mouse position mPositionPix.x = static_cast<float>(input->GetMouseX()); mPositionPix.y = static_cast<float>(input->GetMouseY()); //Send event with new position NewMousePosInfo newposinfo(mPositionPix); SingletonGameEventMgr::Instance()->QueueEvent( EventDataPointer(new NewMousePosEvent(Event_NewMousePos,newposinfo)) ); //Shoot command if(input->OnMouseButtonPress(IND_MBUTTON_LEFT)) { //Send event with new position Vector2 reltocenterpos (mPositionPix.x - mResX/2, mResY/2 - mPositionPix.y ); reltocenterpos.Normalise(); ShootCommandInfo commandinfo(reltocenterpos); SingletonGameEventMgr::Instance()->QueueEvent( EventDataPointer(new ShootCommandEvent(Event_ShootCommand,commandinfo)) ); } }
void Game::RecieveData() { //********************* recieve data ******************************** // create a packet stream object for recieving and sending data PacketStream PS; // now we want to recieve any data char recieved[100] = "n"; // set to "n" as a flag that it is unpopulated Net::GetInstance()->ReceiveData(recieved); // if the array has been populated if(recieved[0] != 'n') { // if we recieve any valid data and connectedToPeer is false if(!m_connectedToPeer) { /// we are now connected to a peer m_connectedToPeer = true; SendStartRace(); } PS.fromCharArray(recieved); int e; PS.readInt(e); while(e != ENDOFMESSAGE) { switch (e) { case STATEDATA: { float x = m_pOtherCar->X(); float y = m_pOtherCar->Y(); float angle = m_pOtherCar->GetAngleY(); float directionX = m_pOtherCar->DirectionX(); float directionY = m_pOtherCar->DirectionY(); float topSpeed = m_pOtherCar->TopSpeed(); float speed = m_pOtherCar->Speed(); float friction = m_pOtherCar->Friction(); PS.readFloat(x); PS.readFloat(y); PS.readFloat(angle); PS.readFloat(directionX); PS.readFloat(directionY); PS.readFloat(topSpeed); PS.readFloat(speed); PS.readFloat(friction); if(m_packetTransferState == CONSTANT) { m_pOtherCar->SetX(x); m_pOtherCar->SetY(y); m_pOtherCar->SetAngleY(angle); } else { // set this first so we can determine if the car should accelerate m_otherCarLastSpeed = m_pOtherCar->Speed(); // set positional data of other car // we want a smooth movement to the new point Vector2 newPos(x,y); // get the vector between the new pos and old pos Vector2 vector = newPos-m_pOtherCar->Position(); // if we are a good bit away then snap if(vector.Length() > 20) { m_pOtherCar->SetX(x); m_pOtherCar->SetY(y); } else if(vector.Length() > 2) { // normalise to find the direction vector.Normalise(); directionX = vector.X; directionY = vector.Y; } m_pOtherCar->SetAngleY(angle); m_pOtherCar->SetDirectionX(directionX); m_pOtherCar->SetDirectionY(directionY); m_pOtherCar->SetTopSpeed(topSpeed); m_pOtherCar->SetSpeed(speed); m_pOtherCar->SetFriction(friction); } } break; case FINISHEDRACE: { // the race is over m_raceFinished = true; // if the host recieved this message then they are not the winner if(m_host) { m_hostWon = false; } else { m_hostWon = true; } } break; case STARTRACE: { if(m_host) { m_pMyCar->SetX(m_hostCarStartPosX); m_pMyCar->SetY(m_hostCarStartPosY); m_pOtherCar->SetX(m_joinCarStartPosX); m_pOtherCar->SetY(m_joinCarStartPosY); } else { m_pMyCar->SetX(m_joinCarStartPosX); m_pMyCar->SetY(m_joinCarStartPosY); m_pOtherCar->SetX(m_hostCarStartPosX); m_pOtherCar->SetY(m_hostCarStartPosY); } m_raceStarted = true; } break; } PS.readInt(e); } m_lastPacketRecieveTime = GetTickCount(); } // if we recieved an empty packet the we have reached a timeout else if(GetTickCount() - m_lastPacketRecieveTime > CONNECTION_TIMEOUT) { // then we assume that we are no longer connected to the peer m_connectedToPeer = false; m_raceStarted = false; } //******************************************************************* }
/********************************************************** C# code from http://www.codeproject.com/Articles/15573/2D-Polyhedron-Collision-Detection */ bool Polyhedron::DoesCollide(Vector2* Velocity, Polyhedron* CheckWith) { bool Intersect = true; bool WillIntersect = true; int edgeCountA = Edges->count; int edgeCountB = CheckWith->Edges->count; // float minIntervalDistance = 99999999; // Vector2* translationAxis = new Vector2( 0, 0 ); Vector2* edge; // Loop through all the edges of both Polyhedrons for( int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++ ) { if( edgeIndex < edgeCountA ) { edge = Edges->ItemAt<Vector2*>(edgeIndex); } else { edge = CheckWith->Edges->ItemAt<Vector2*>(edgeIndex - edgeCountA); } // ===== 1. Find if the Polyhedrons are currently intersecting ===== // Find the axis perpendicular to the current edge Vector2* axis = new Vector2(-edge->Y, edge->X); axis->Normalise(); // Find the projection of the Polyhedron on the current axis float minA = 0; float minB = 0; float maxA = 0; float maxB = 0; Project(axis, &minA, &maxA); CheckWith->Project(axis, &minB, &maxB); // Check if the Polyhedron projections are currentlty intersecting if( IntervalDistance(minA, maxA, minB, maxB) > 0 ) { Intersect = false; } // ===== 2. Now find if the Polyhedrons *will* intersect ===== // Project the velocity on the current axis float velocityProjection = axis->DotProduct( Velocity ); // Get the projection of Polyhedron A during the movement if( velocityProjection < 0 ) { minA += velocityProjection; } else { maxA += velocityProjection; } // Do the same test as above for the new projection float intervalDistance = IntervalDistance( minA, maxA, minB, maxB ); if( intervalDistance > 0 ) { WillIntersect = false; } delete axis; // If the Polyhedrons are not intersecting and won't intersect, exit the loop if( !Intersect && !WillIntersect) { break; } /* // Check if the current interval distance is the minimum one. If so store // the interval distance and the current distance. // This will be used to calculate the minimum translation vector intervalDistance = Math.Abs(intervalDistance); if (intervalDistance < minIntervalDistance) { minIntervalDistance = intervalDistance; translationAxis = axis; Vector d = PolyhedronA.Center - PolyhedronB.Center; if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis; } */ // int xcv = 1; } // The minimum translation vector can be used to push the Polyhedrons appart. // First moves the Polyhedrons by their velocity // then move PolyhedronA by MinimumTranslationVector. // if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance; return (Intersect | WillIntersect); }
Vector2 Vector2::NormalisedCopy(void) const { Vector2 ret = *this; ret.Normalise(); return ret; }
Vector2 Vector2::GetNormal() { Vector2 temp = *this; temp.Normalise(); return temp; }
bool AnimationSkeleton::Intersect(bool isHFlipped, Vector3 & skeletonWorldPos, AnimationSkeletonFramePiece & framePiece, Vector2 & otherStart, Vector2 & otherEnd, Vector2 & intersectPointOut) { Vector2 pieceWorldStart(skeletonWorldPos.X + framePiece.mStartPos.X, skeletonWorldPos.Y + framePiece.mStartPos.Y); Vector2 pieceWorldEnd(skeletonWorldPos.X + framePiece.mEndPos.X, skeletonWorldPos.Y + framePiece.mEndPos.Y); if (isHFlipped) { pieceWorldStart.X = skeletonWorldPos.X - framePiece.mStartPos.X; pieceWorldEnd.X = skeletonWorldPos.X - framePiece.mEndPos.X; } // Calculate matrix determinants float det1 = (pieceWorldStart.X * pieceWorldEnd.Y) - (pieceWorldStart.Y * pieceWorldEnd.X); float det2 = (otherStart.X * otherEnd.Y) - (otherStart.Y * otherEnd.X); float det3 = ((pieceWorldStart.X - pieceWorldEnd.X) * (otherStart.Y - otherEnd.Y)) - ((pieceWorldStart.Y - pieceWorldEnd.Y) * (otherStart.X - otherEnd.X)); if (det3 >= -0.00000001f && det3 <= 0.00000001f) return false; // Otherwise calculate the point of intersection: intersectPointOut.X = (det1 * (otherStart.X - otherEnd.X)) - ((pieceWorldStart.X - pieceWorldEnd.X) * det2); intersectPointOut.X /= det3; intersectPointOut.Y = (det1 * (otherStart.Y - otherEnd.Y)) - ((pieceWorldStart.Y - pieceWorldEnd.Y) * det2); intersectPointOut.Y /= det3; // Make sure the point is along both lines: get it relative to the start point of both lines Vector2 r1 = intersectPointOut - pieceWorldStart; Vector2 r2 = intersectPointOut - otherStart; Vector2 otherLineDistance = otherEnd - otherStart; Vector2 otherLineDirection = otherLineDistance; otherLineDirection.Normalise(); // TODO: optimisation opportunity // Do a dot product with both line directions to see if it is past the end of either of the two lines: float dot1 = r1.Dot(framePiece.mLineDirection); float dot2 = r2.Dot(otherLineDirection); // If either dot is negative then the point is past the beginning of one of the lines: if (dot1 < 0 || dot2 < 0) { return false; } // If either dot exceeds the length of the line then point is past the end of the line: if (dot1 > framePiece.mLength) { return false; } if (dot2 > otherLineDistance.Length()) // TODO: optimisation opportunity { return false; } return true; }
int main() { Vector2<int> vec2(12,25); Vector2<int> vec3(13,24); Vector2<int> storage; std::cout << "Vector2: \n\n"; storage = vec3 + vec2; std::cout << "Add:" << "(" << storage.x << "," << storage.y << ")" << std::endl; storage = vec3 - vec2; std::cout << "Subtract:" << "(" << storage.x << "," << storage.y << ")" << std::endl; storage = vec3 / vec2; std::cout << "Divide:" << "(" << storage.x << "," << storage.y << ")" << std::endl; storage = vec3 * vec2; std::cout << "Multiply:" << "(" << storage.x << "," << storage.y << ")" << std::endl; storage = vec3 % vec2; std::cout << "Modulus:" << "(" << storage.x << "," << storage.y << "," << ")" << std::endl; int sto = storage.Dot(vec2, vec3); std::cout << "Dot product: " << sto << std::endl; int mg = storage.Mag(vec2); std::cout << "Magnitude: " << mg << std::endl; Vector2<int> norm = storage.Normalise(vec2); std::cout << "Normalize:" << "(" << norm.x << "," << norm.y << "," << ")\n\n" << std::endl; Vector3<int> vec1(12, 12, 12); Vector3<int> vec4(12, 12, 12); Vector3<int> storage2; std::cout << "Vector3: \n\n"; storage2 = vec1 + vec4; std::cout << "Add:" << "(" << storage2.x << "," << storage2.y << "," << storage2.z << ")" << std::endl; storage2 = vec1 - vec4; std::cout << "Subtract:" << "(" << storage2.x << "," << storage2.y << "," << storage2.z << ")" << std::endl; storage2 = vec1 / vec4; std::cout << "Divide:" << "(" << storage2.x << "," << storage2.y << "," << storage2.z << ")" << std::endl; storage2 = vec1 * vec4; std::cout << "Multiply:" << "(" << storage2.x << "," << storage2.y << "," << storage2.z << ")" << std::endl; storage2 = vec1 % vec4; std::cout << "Modulus:" << "(" << storage2.x << "," << storage2.y << "," << storage2.z << ")" << std::endl; int Dot = storage2.Dot(vec1, vec4); std::cout << "Dot Product is: " << Dot << std::endl; Vector3<int> cross = storage2.Cross(vec1, vec4); std::cout << "Cross Product is: " << cross.x << "," << cross.y << cross.z << std::endl; int Mag = storage2.Mag(vec1); std::cout << "Magnitude Product is: " << Mag << std::endl; Vector3<int> Norm = storage2.Normalise(vec1); std::cout << "Normalised:" << "(" << Norm.x << "," << Norm.y << "," << Norm.z << ")\n" << std::endl; std::cout << "Color: \n\n"; Color<int> color; Color<int> boo1(12, 12, 12, 12); Color<int> boo2(13, 13, 13, 13); Color<int> test; test = boo1 + boo2; std::cout << "Add:" << "(" << test.r << "," << test.g << "," << test.b << "," << test.a << ")" << std::endl; test = boo1 - boo2; std::cout << "Subtract:" << "(" << test.r << "," << test.g << "," << test.b << "," << test.a << ")" << std::endl; test = boo1 * boo2; std::cout << "Multiply:" << "(" << test.r << "," << test.g << "," << test.b << "," << test.a << ")" << std::endl; test = boo1 / boo2; std::cout << "Quotient:" << "(" << test.r << "," << test.g << "," << test.b << "," << test.a << ")" << std::endl; test = boo1 % boo2; std::cout << "Modulus:" << "(" << test.r << "," << test.g << "," << test.b << "," << test.a << ")" << std::endl; test = test.Normalise(boo1); std::cout << "Normalize:" << "(" << test.r << "," << test.g << "," << test.b << "," << test.a << ")" << std::endl; float mag = test.Mag(boo1); std::cout << "Magnitude: " << mag; Color<int> rgba = color.HexConv("#FFFFFF"); std::cout << "\nRGBA Values Are : (" << rgba.r << "," << rgba.g << "," << rgba.b << "," << rgba.a << ")\n"; system("PAUSE"); return 0; }