void Faces::breakBody() { if (isThereMbodybool) delMbody(); float movX = (mBody->GetWorldCenter().x * BOX2D_SCALE); float movY = (mBody->GetWorldCenter().y * BOX2D_SCALE * (-1.f)); float cx = posX + movX; float cy = posY + movY; // float movX = _toPixelX(mBody->GetWorldCenter().x) + posX; // float movY = _toPixelY(mBody->GetWorldCenter().y) + posY; // float movX = posX; // float movY = posY; // get intervald virtices // Add first point of blob polygon shape. b2Vec2 first = b2Vec2(0, 0); first.x = mVertice[0].x + movX; first.y = mVertice[0].y + movY; mVerticeDiv[0] = first; // Add middle points of blob polygon shape. for (int i = 1; i < (fragNum - 1); i++) { b2Vec2 temp = b2Vec2(0, 0); temp.x = mVertice[kSAMPLING_INTV * i].x + movX; temp.y = mVertice[kSAMPLING_INTV * i].y + movY; mVerticeDiv[i] = temp; } // Add end point of blob polygon shape b2Vec2 last = b2Vec2(0, 0); last.x = mVertice[kMAX_VERTICES - 1].x + movX; last.y = mVertice[kMAX_VERTICES - 1].y + movY; mVerticeDiv[fragNum - 1] = last; for (int i = 0; i < fragNum; i++){ // cout << i << ": " << mVerticeDiv[i].x << " / " << mVerticeDiv[i].y << endl; } int fragIdx = 0; for (int i = 0; i < fragNum - 1; i++){ b2Vec2 vertices[3]; // b2Vec2 a = b2Vec2(_toWorldX(movX), _toWorldY(movY)); b2Vec2 a = b2Vec2(_toWorldX(cx), _toWorldY(cy)); b2Vec2 b = b2Vec2(_toWorldX(mVerticeDiv[i].x), _toWorldY(mVerticeDiv[i].y)); b2Vec2 c = b2Vec2(_toWorldX(mVerticeDiv[i+1].x), _toWorldY(mVerticeDiv[i+1].y)); // b2Vec2 a = b2Vec2(1, 1); // b2Vec2 b = b2Vec2(2, 3); // b2Vec2 c = b2Vec2(0, 0); // ofVec2f vh(-1, 0); // ofVec2f vv(0, -1); ofVec2f vAB(b.x - a.x, b.y - a.y); ofVec2f vBC(c.x - b.x, c.y - b.y); // ofVec2f vAC(c.x - a.x, c.y - a.y); // vh.normalize(); // vv.normalize(); vAB.normalize(); vBC.normalize(); // vAC.normalize(); // float d = perp_dot(b - a, c - b); float d = perp_dot(vAB, vBC); if(d < 0){ // cout << "RIGHT\n"; }else{ // cout << "LEFT\n"; } // float angleHAB = acos(vh.dot(vAB)); // float angleHAC = acos(vh.dot(vAC)); // float angleVAB = acos(vv.dot(vAB)); // float angleVAC = acos(vv.dot(vAC)); // float angleABBC = acos(vAB.dot(vBC)); // // // cout << "angleHAB : " << (-1.f) * _toDegree(angleHAB) << endl; // cout << "angleHAC : " << (-1.f) * _toDegree(angleHAC) << endl; // // cout << "angleVAB : " << (-1.f) * _toDegree(angleVAB) << endl; // cout << "angleVAC : " << (-1.f) * _toDegree(angleVAC) << endl; // // cout << "angleAB-BC : " << (-1.f) * _toDegree(angleABBC) << endl; for (int j = 0; j < 3; j++){ // vertices[0] = b2Vec2(_toWorldX(movX), _toWorldY(movY)); vertices[0] = b2Vec2(_toWorldX(cx), _toWorldY(cy)); vertices[1] = b2Vec2(_toWorldX(mVerticeDiv[i].x), _toWorldY(mVerticeDiv[i].y)); vertices[2] = b2Vec2(_toWorldX(mVerticeDiv[i+1].x), _toWorldY(mVerticeDiv[i+1].y)); } // To keep CCW direction. if (d < 0){ // cout << "2 and 1 changed\n" << endl; vertices[1] = b2Vec2(_toWorldX(mVerticeDiv[i+1].x), _toWorldY(mVerticeDiv[i+1].y)); vertices[2] = b2Vec2(_toWorldX(mVerticeDiv[i].x), _toWorldY(mVerticeDiv[i].y)); } // cout << "triangle " << i << " : " << "\n" << // vertices[0].x << " / " << vertices[0].y << "\n" << // vertices[1].x << " / " << vertices[1].y << "\n" << // vertices[2].x << " / " << vertices[2].y << "\n" << // endl; // If the area did not have minus value. if(getArea(&vertices[0], 3) > 0){ Frag * aFrag = new Frag(mWorld, movX, movY, vertices, index, fragIdx, fragOutlineColor); aFrag->setLifeLong(fragLifeTime); // Frag will die after n Frame. 0 means 'immortal'. mFrags.push_back(aFrag); fragIdx++; } } // breakFrags(); pushForce(cx, cy); }
void SpaceshipGame::update(long elapsedTime) { // Calculate elapsed time in seconds float t = (float)elapsedTime / 1000.0; if (!_finished) { _time += t; // Play the background track if (_backgroundSound->getState() != AudioSource::PLAYING) _backgroundSound->play(); } else { // Stop the background track if (_backgroundSound->getState() != AudioSource::STOPPED) _backgroundSound->stop(); _throttle = 0.0f; } // Set initial force due to gravity _force.set(0, -GRAVITATIONAL_FORCE); // While we are pushing/touching the screen, apply a push force vector based on the distance from // the touch point to the center of the space ship. if (_pushing) { // Get the center point of the space ship in screen coordinates Vector3 shipCenterScreen; _scene->getActiveCamera()->project(getViewport(), _shipGroupNode->getBoundingSphere().center, &shipCenterScreen.x, &shipCenterScreen.y); // Compute a screen-space vector between the center point of the ship and the touch point. // We will use this vector to apply a "pushing" force to the space ship, similar to what // happens when you hold a magnet close to an object with opposite polarity. Vector2 pushForce((shipCenterScreen.x - _pushPoint.x), -(shipCenterScreen.y - _pushPoint.y)); // Transform the vector so that a smaller magnitude emits a larger force and applying the // maximum touch distance. float distance = (std::max)(TOUCH_DISTANCE_MAX - pushForce.length(), 0.0f); pushForce.normalize(); pushForce.scale(distance * FORCE_SCALE); _force.add(pushForce); // Compute a throttle value based on our force vector, minus gravity Vector2 throttleVector(_force.x, _force.y + GRAVITATIONAL_FORCE); _throttle += throttleVector.length() / FORCE_MAX * t; } else { // Gradually decrease the throttle if (_throttle > 0.0f) { _throttle *= 1.0f - t; } } // Clamp the throttle _throttle = CLAMP(_throttle, 0.0f, 1.0f); // Update acceleration (a = F/m) _acceleration.set(_force.x / MASS, _force.y / MASS); // Update velocity (v1 = v0 + at) _velocity.x += _acceleration.x * t; _velocity.y += _acceleration.y * t; // Clamp velocity to its maximum range _velocity.x = CLAMP(_velocity.x, -VELOCITY_MAX, VELOCITY_MAX); _velocity.y = CLAMP(_velocity.y, -VELOCITY_MAX, VELOCITY_MAX); // Move the spaceship based on its current velocity (x1 = x0 + vt) _shipGroupNode->translate(_velocity.x * t, _velocity.y * t, 0); // Check for collisions handleCollisions(t); // Update camera updateCamera(); // Reset ship rotation _shipGroupNode->setRotation(_initialShipRot); // Apply ship tilt if (_force.x != 0 && abs(_velocity.x) > 0.1f) { // Compute an angle based on the dot product between the force vector and the Y axis Vector2 fn; _force.normalize(&fn); float angle = MATH_RAD_TO_DEG(acos(Vector2::dot(Vector2(0, 1), fn))); if (_force.x > 0) angle = -angle; angle *= _throttle * t; _shipTilt += angle; _shipTilt = _shipTilt < -SHIP_TILT_MAX ? -SHIP_TILT_MAX : (_shipTilt > SHIP_TILT_MAX ? SHIP_TILT_MAX : _shipTilt); } else { // Interpolate tilt back towards zero when no force is applied _shipTilt = (_shipTilt + ((0 - _shipTilt) * t * 2.0f)); } _shipGroupNode->rotateZ(MATH_DEG_TO_RAD(_shipTilt)); if (_throttle > MATH_EPSILON) { // Apply ship spin _shipNode->rotateY(MATH_DEG_TO_RAD(SHIP_ROTATE_SPEED_MAX * t * _throttle)); // Play sound effect if (_spaceshipSound->getState() != AudioSource::PLAYING) _spaceshipSound->play(); // Set the pitch based on the throttle _spaceshipSound->setPitch(_throttle * SOUND_PITCH_SCALE); } else { // Stop sound effect _spaceshipSound->stop(); } // Modify ship glow effect based on the throttle _glowDiffuseParameter->setValue(Vector4(1, 1, 1, _throttle * ENGINE_POWER)); _shipSpecularParameter->setValue(SPECULAR - ((SPECULAR-2.0f) * _throttle)); }