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