Exemple #1
0
bool Convex::hasCollided(Convex* other)
{
	sf::Vector2f collisionPoint, betweenCorners;


	for (int i = 0; i < other->getPointCount(); i++)
	{
		for (int j = 0; j < getPointCount(); j++)
		{
			if (j < getPointCount() - 1)
			{
				sf::Vector2f collisionPoint(other->getPoint(i).x - getPoint(j).x,
					other->getPoint(i).y - getPoint(j).y);
				sf::Vector2f betweenCorners(getPoint(j + 1).x - getPoint(j).x,
					getPoint(j + 1).y - getPoint(j).y);
			}
			else
			{
				sf::Vector2f collisionPoint(other->getPoint(i).x - getPoint(j).x,
					other->getPoint(i).y - getPoint(j).y);
				sf::Vector2f betweenCorners(getPoint(0).x - getPoint(j).x,
					getPoint(0).y - getPoint(j).y);
			}

			if (vectorProduct(betweenCorners.x, betweenCorners.y, collisionPoint.x, collisionPoint.y) > 0)
			{
				return false;
			}
		}
	}

	for (int i = 0; i < this->getPointCount(); i++)
	{
		for (int j = 0; j < other->getPointCount(); j++)
		{
			if (j < other->getPointCount() - 1)
			{
				sf::Vector2f collisionPoint(this->getPoint(i).x - other->getPoint(j).x,
					this->getPoint(i).y - other->getPoint(j).y);
				sf::Vector2f betweenCorners(other->getPoint(j + 1).x - other->getPoint(j).x,
					other->getPoint(j + 1).y - other->getPoint(j).y);
			}
			else
			{
				sf::Vector2f collisionPoint(this->getPoint(i).x - other->getPoint(j).x,
					this->getPoint(i).y - other->getPoint(j).y);
				sf::Vector2f betweenCorners(other->getPoint(0).x -other->getPoint(j).x,
					other->getPoint(0).y - other->getPoint(j).y);
			}

			if (vectorProduct(betweenCorners.x, betweenCorners.y, collisionPoint.x, collisionPoint.y) > 0)
			{
				return false;
			}
		}
	}
	return true;
}
Exemple #2
0
void Convex::applyChanges(int index, sf::Vector2f* collisionNormal)
{
	float radius = getRadius(index);

	sf::Vector2f collisionPoint(getPoint(index).x - _massCenter.x,
		getPoint(index).y - _massCenter.y);

	_momentOfInertia = _mass * pow(radius, 2);

	float impulse = getImpulse(&collisionPoint, collisionNormal);

	_velocity.x += impulse / _mass * collisionNormal->x;
	_velocity.y += impulse / _mass * collisionNormal->y;

	_angularVelocity = _angularVelocity + impulse / _momentOfInertia * (collisionPoint.x * collisionNormal->y - collisionPoint.y * collisionNormal->x);
}
void DynamicEntity::checkWrapperPartners()
{
	for (unsigned int i = 0; i < wrapperPartners.size(); ++i)
	{
		Entity* p = wrapperPartners[i];
		if (CollisionTester::areWrapperColliding(this, p))
		{
			GameVector collisionPoint(0,0);
			if (CollisionTester::areColliding(this, p, &collisionPoint))
			{
				if (not Entity::areCollisionPartners(this, p))
				{
					addCollisionPartner(p);
					p->addCollisionPartner(this);
					// TODO throw enter event
				}
				PhysicsHandler::handlePhysics(this, p, collisionPoint);

				this->setChanged(true);
				p->setChanged(true);
			}
			else
			{
				if (Entity::areCollisionPartners(this, p))
				{
					removeCollisionPartner(p);
					p->removeCollisionPartner(this);
					// TODO throw exit event
				}
			}
		}
		else
		{
			removeWrapperPartner(p);
			p->removeWrapperPartner(this);
		}
	}
}
Exemple #4
0
int jeu(Cube * cube, struct SItem * it, int nbItem) {
  Bouton ** b;
  SDL_Rect rimg[6] = {
    { POS_X_CUBISO + 3, POS_Y_CUBISO + cube->nbCubLig * OFFSET_Y_H_CUBISO +
      cube->nbCubLig * 53 + 12, 0, 0 },
    { POS_X_CUBISO + cube->nbCubLig * OFFSET_X_H_CUBISO + 22 - 6,
      POS_Y_CUBISO + cube->nbCubLig * OFFSET_Y_H_CUBISO +
      (cube->nbCubLig - 1) * OFFSET_Y_H_CUBISO + cube->nbCubLig * 53 + 12, 0, 0 },
    { POS_X_CUBISO, POS_Y_CUBISO + (cube->nbCubLig - 1) * OFFSET_Y_H_CUBISO - 15 + 10, 0, 0 },
    { POS_X_CUBISO + cube->nbCubLig * OFFSET_X_H_CUBISO + 18, POS_Y_CUBISO - 15 + 10, 0, 0 },
    { POS_X_CUBISO + cube->nbCubLig * (OFFSET_X_H_CUBISO * 2 ) + 10,
      POS_Y_CUBISO + cube->nbCubLig * OFFSET_Y_H_CUBISO + 15, 0, 0 },
    { POS_X_CUBISO - 27, POS_Y_CUBISO + cube->nbCubLig * OFFSET_Y_H_CUBISO + 15, 0, 0 }
  };
  SDL_Rect roff[6] = {
    { OFFSET_X_H_CUBISO, OFFSET_Y_H_CUBISO, 0, 0 },
    { OFFSET_X_H_CUBISO, -OFFSET_Y_H_CUBISO, 0, 0 },
    { OFFSET_X_H_CUBISO, -OFFSET_Y_H_CUBISO, 0, 0 },
    { OFFSET_X_H_CUBISO, OFFSET_Y_H_CUBISO, 0, 0 },
    { 0, 53, 0, 0 },
    { 0, 53, 0, 0 }
  };
  Input * in;
  int ret = M_MENU;
  int nbBtn;
  int done;
  int clic;
  int timer;
  int i, j, k;
  
  if (cube == NULL)
    return ret;
  
  in = newEvent();
  
  nbBtn = nbItem + cube->nbCubLig * 6;
  b = emalloc((nbBtn + 1) * sizeof **b, "Erreur d'allocation de boutons.\n");
  b[nbBtn] = NULL;
  
  for (i = 0, j = 0; i < nbItem; i++, j++)
    b[i] = creerBoutonTexte(it[i].pItemName, SCR_W - g_boutons[0]->w - 12,
                            SCR_H - 6 - (nbItem - i) * (g_boutons[0]->h + 6), 1);
  
  for (k = 0; k < 6; k++)
    for (i = 0; i < cube->nbCubLig; i++, j++)
      b[j] = creerBoutonImage(k * 3, rimg[k].x + roff[k].x * i,
                              rimg[k].y + roff[k].y * i, 1);
  
  refreshScreen();
  
  timer = 0;
  clic = 0;
  done = 0;
  while (!done) {
    updateEvents(in);
    
    if (in->quit) {
      done = 1;
      ret = M_QUIT;
    }
    
    for (i = 0; i < nbBtn; i++) {
      if (b[i]->actif) {
        if (collisionPoint(&b[i]->r, &in->mouse)) {
          /* Si on clique */
          if (!clic && (in->mousebuttons[1] || in->mousebuttons[2])) {
            clic = 1;
            b[i]->etat = BTN_ETAT_CLIC;
            b[i]->majAff = 1;
          }
          /* Si on relâche le clic */
          else if (clic && b[i]->etat == BTN_ETAT_CLIC &&
                   !in->mousebuttons[1] && !in->mousebuttons[2]) {
            clic = 0;
            b[i]->etat = BTN_ETAT_NORMAL;
            b[i]->majAff = 1;
            
            if (i < nbItem) {
              if (it[i].nItemVal == M_MENU || it[i].nItemVal == M_QUIT) {
                ret = it[i].nItemVal;
                if (it[i].pVal)
                  *it[i].pVal = it[i].nVal;
                done = 1;
              }
              else if (it[i].nItemVal == M_MELANGE) {
                melangerCube(cube);
                timer = 0;
                cube->tpsTotal = 0;
                cube->nbCoups = 0;
              }
              else if (it[i].nItemVal == M_REINIT) {
                refreshScreen();
                initCube(cube, cube->nbCubLig);
                timer = 0;
              }
              else if (it[i].nItemVal == M_SAUVE) {
                sauverCube(cube);
              }
            }
            else if (i >= nbItem) {
              int tmp = i - nbItem;
              
              cube->nbCoups++;
              if (timer == 0)
                timer = 1;
              
              /* Ca va crescendo on teste la borne la plus basse et ainsi de suite
               * sans retester plus bas, c'est déjà test avant */
              /* Flèche haut gauche */
              if (tmp < cube->nbCubLig) {
                rotationCubeEntier(cube, R_GAUCHE);
                mouvement(cube, tmp, R_BAS);
                rotationCubeEntier(cube, R_DROITE);
              }
              /* Flèches haut droite */
              else if (tmp < cube->nbCubLig * 2) {
                tmp -= cube->nbCubLig;
                mouvement(cube, tmp, R_BAS);
              }
              /* Flèches bas gauche */
              else if (tmp < cube->nbCubLig * 3) {
                tmp -= (cube->nbCubLig * 2);
                mouvement(cube, tmp, R_HAUT);
              }
              /* Flèches bas droite */
              else if (tmp < cube->nbCubLig * 4) {
                tmp -= (cube->nbCubLig * 3);
                rotationCubeEntier(cube, R_GAUCHE);
                mouvement(cube, tmp, R_HAUT);
                rotationCubeEntier(cube, R_DROITE);
              }
              /* Flèches droite */
              else if (tmp < cube->nbCubLig * 5) {
                tmp -= (cube->nbCubLig * 4);
                mouvement(cube, tmp, R_DROITE);
              }
              /* Flèches gauche */
              else if (tmp < cube->nbCubLig * 6) {
                tmp -= (cube->nbCubLig * 5);
                mouvement(cube, tmp, R_GAUCHE);
              }
              else {
                cube->nbCoups--;
                aprintf("Bouton inconnu.\n");
              }
            }
            else {
              aprintf("Bouton inconnu.\n");
            }
          }
          else if (b[i]->etat != BTN_ETAT_CLIC) {
            if (b[i]->etat != BTN_ETAT_SURVOLE)
              b[i]->majAff = 1;
            b[i]->etat = BTN_ETAT_SURVOLE;
          }
        }
        else if (b[i]->etat != BTN_ETAT_CLIC) {
          if (b[i]->etat != BTN_ETAT_NORMAL)
            b[i]->majAff = 1;
          b[i]->etat = BTN_ETAT_NORMAL;
        }
      }
    }
    
    if (clic && !in->mousebuttons[1] && !in->mousebuttons[2]) {
      clic = 0;
      for (i = 0; i < nbBtn; i++)
        if (b[i]->etat == BTN_ETAT_CLIC) {
          b[i]->etat = BTN_ETAT_NORMAL;
          b[i]->majAff = 1;
        }
    }
    
    if (timer)
      cube->tpsTotal += TICK;
    
    affiche(BCK_JEU, cube, b);
  }
  
  for (i = 0; i < nbBtn; i++)
    detruireBouton(&b[i]);
  free(b);
  deleteEvent(&in);
  
  return ret;
}
void PSLGSSkeleton::handleSwitchEvent(PSLGEdge* event) {
	PSLGVertex *u, *v;  //event的两个顶点: u指向CONVEX_VERTEX; v指向REFLEX_VERTEX或MOVINGMOVING_STEINER_VERTEX
	
	if ( event->tailvex->type == CONVEX_VERTEX ) {
		u = event->tailvex;
		v = event->headvex;
	} else {
		u = event->headvex;
		v = event->tailvex;
	}
	PSLGEdge *uin, *uout; //u的入边与出边
	PSLGEdge *vin, *vout, *vedge;  //v的入边与出边,以及v的另一条不在多边形上的邻边
	uin = u->firstin;
	uout = u->firstout;
	vin = v->firstin;
	vout = v->firstout;
	if( vin->hedge != NULL ) {
		vedge = vin->hedge;
	} else {
		vedge = vout->tedge;
	}
	QPointF collisionPoint( u->movedPosition( event->vanishTime ) ); //两顶点相遇的点
	addTriangleMesh( v->firstin->tailvex, v, collisionPoint, event->vanishTime );
	addTriangleMesh( v, v->firstout->headvex, collisionPoint, event->vanishTime );
	//如果v为REFLEX_VERTEX,增加两条直骨架边;否则不增加直骨架边
	if ( v->type == PSLGVertexType::REFLEX_VERTEX ) { 
		skeleton.push_back( QLineF( u->oriPosition, collisionPoint ) );
		skeleton.push_back( QLineF( v->oriPosition, collisionPoint ) );
	} 
	//找到vedge的另一个端点
	PSLGVertex* vedge2v; //vedge不同于v的顶点
	if ( vedge->tailvex == v ) {
		vedge2v = vedge->headvex;
	} else {
		vedge2v = vedge->tailvex;
	}

	if ( event->tailvex == u && uin->tailvex == vedge2v ) {
		//三个点u,v,vedge2v一起湮灭
		if ( v->type == PSLGVertexType::MOVING_STEINER_VERTEX ) {
			skeleton.push_back( QLineF( u->oriPosition, collisionPoint ) );
			if ( vedge2v->type == PSLGVertexType::REFLEX_VERTEX ) {
				skeleton.push_back( QLineF( vedge2v->oriPosition, collisionPoint ) );
			}
			addTriangleMesh( vedge2v->firstin->tailvex, vedge2v, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v, u, collisionPoint, event->vanishTime );
			addTriangleMesh( vin->tailvex, v, collisionPoint, event->vanishTime );
			addTriangleMesh( v, vout->headvex, collisionPoint, event->vanishTime );
		} else {
			addTriangleMesh( vedge2v, u, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v->firstin->tailvex, vedge2v, collisionPoint, event->vanishTime );
		}
		//保留v点,v点的两条邻边为vout, vedge2v->firstin
		v->firstin = vedge2v->firstin;
		vedge2v->firstin->headvex = v;
		v->firstout->tedge = NULL;
		v->firstin->hedge = NULL;
		//计算v点速度
		v->oriPosition.setX( collisionPoint.x() );
		v->oriPosition.setY( collisionPoint.y() );
		v->startTime = event->vanishTime;
		PSLGGraph::calcVertexProperty( v );
		eventQueue->heapUpdateKey( v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstin ) );
		eventQueue->heapUpdateKey( v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstout ) );
		//删除uin,uout,vedge, 删除u,vedge2v
		eventQueue->minHeapRemove( uin->heapIndex );
		eventQueue->minHeapRemove( vedge->heapIndex );
		delete uin;
		delete vedge;
		delete event;
		delete u;
		delete vedge2v;
		return;
	} else if ( event->headvex == u && uout->headvex == vedge2v ){
		if ( v->type == PSLGVertexType::MOVING_STEINER_VERTEX ) {
			skeleton.push_back( QLineF( u->oriPosition, collisionPoint ) );
			if ( vedge2v->type == PSLGVertexType::REFLEX_VERTEX ) {
				skeleton.push_back( QLineF( vedge2v->oriPosition, collisionPoint ) );
			}
			addTriangleMesh( u, vedge2v, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v, vedge2v->firstout->headvex, collisionPoint, event->vanishTime );
			addTriangleMesh( vin->tailvex, v, collisionPoint, event->vanishTime );
			addTriangleMesh( v, vout->headvex, collisionPoint, event->vanishTime );
		} else {
			addTriangleMesh( u, vedge2v, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v, vedge2v->firstout->headvex, collisionPoint, event->vanishTime );
		}
		//保留v点,v点的两条邻边为vin vedge2v->firstout, 删除uin,uout,vedge
		v->firstout = vedge2v->firstout;
		vedge2v->firstout->tailvex = v;
		v->firstin->hedge = v->firstout->tedge = NULL;
		//计算v点速度
		v->oriPosition.setX( collisionPoint.x() );
		v->oriPosition.setY( collisionPoint.y() );
		v->startTime = event->vanishTime;
		PSLGGraph::calcVertexProperty( v );
		eventQueue->heapUpdateKey( v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstin ) );
		eventQueue->heapUpdateKey( v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstout ) );
		//删除uin,uout,vedge, 删除u,vedge2v
		eventQueue->minHeapRemove( uout->heapIndex );
		eventQueue->minHeapRemove( vedge->heapIndex );
		delete uout;
		delete vedge;
		delete event;
		delete u;
		delete vedge2v;
		return;
	}

	if ( event->tailvex == u ) {  //event的方向是从u到v
		addTriangleMesh( uin->tailvex, u, collisionPoint, event->vanishTime );
		//将event的方向改为从v到u,并更改event的链接关系
		event->tailvex = v;
		event->headvex = u;
		uin->headvex = v;
		v->firstin = uin;
		v->firstout = event;
		u->firstin = event;
		u->firstout = vout;
		vout->tailvex = u;
		event->tedge = event->hedge = NULL;
		vout->tedge = NULL;
	} else { //event的方向从v到u
		addTriangleMesh( u, uout->headvex, collisionPoint, event->vanishTime );
		//将event的方向设为从u到v
		event->tailvex = u;
		event->headvex = v;
		vin->headvex = u;
		u->firstin = vin;
		u->firstout = event;
		v->firstin = event;
		v->firstout = uout;
		uout->tailvex = v;
		event->tedge = event->hedge = NULL;
		vin->hedge = NULL;
	}
	
	//更新顶点的信息
	if ( v->type == PSLGVertexType::REFLEX_VERTEX ) {
		//u的速度发生变化
		u->oriPosition.setX( collisionPoint.x() );
		u->oriPosition.setY( collisionPoint.y() );
		u->startTime = event->vanishTime;
		if ( u->firstin->tailvex == v ) {
			//PSLGGraph::calcVertexProperty( v->firstin->tailvex, u, u->firstout->headvex );
			PSLGGraph::calcConvexVertexSpeed( v->firstin->tailvex, u, u->firstout->headvex );
			eventQueue->heapUpdateKey( u->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstout ) );
		} else {
			PSLGGraph::calcConvexVertexSpeed( u->firstin->tailvex, u, v->firstout->headvex );
			//PSLGGraph::calcVertexProperty( u->firstin->tailvex, u, v->firstout->headvex );
			eventQueue->heapUpdateKey( u->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstin ) );
		}
	} else {
		if ( u->firstin->tailvex == v ) {
			eventQueue->heapUpdateKey( u->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstout ) );
		} else {
			eventQueue->heapUpdateKey( u->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstin ) );
		}
	}

	//更新vedge的链接结构
	if ( vedge->tailvex == v ) {
		v->firstout->tedge = vedge;
	} else {
		v->firstin->hedge = vedge;
	}
	//v的速度变化
	v->oriPosition.setX( collisionPoint.x() );
	v->oriPosition.setY( collisionPoint.y() );
	v->startTime = event->vanishTime;
	v->type = PSLGVertexType::MOVING_STEINER_VERTEX;

	if ( u->firstin->tailvex == v ) {
		PSLGGraph::calcMovingSteinerSpeed( v, vedge2v, v->firstin->tailvex );
		eventQueue->heapUpdateKey( v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstin ) );
	} else {
		PSLGGraph::calcMovingSteinerSpeed( v, vedge2v, v->firstout->headvex );
		eventQueue->heapUpdateKey( v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstout ) );
	}
	//更新event, vedge的消失时间
	event->vanishTime = std::numeric_limits< double >::max();
	eventQueue->minHeapInsert( event );
	eventQueue->heapUpdateKey( vedge->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge ) );
}