void Consumer::consume(int id, Qt::HANDLE threadID, bool collision) { if (m_threadID == threadID) { qDebug() << "Called from Consumer thread: " << threadID; } else { qDebug() << "Called from the GUI thread: " << threadID; } if (id == 0 || m_main->getBox(id).isNull()) { return; } qDebug() << "ID: " << id; QVariant box = m_main->removeBox(id); if (collision) { emit collisionSignal(box); } else { emit consumedSignal(box); } }
void Simulation::updatePlayers() { /*NOTE: The Simulation behaves as if events during a turn happen simultaneous. * That way the simulation is deterministic, even though (partial) events may * occur in an arbitrary order. This is archived by applying types of event in * a particular order. E.g. player movements never influence each other. * Collisions never influence each other. But movement influences Collision. * Therefor if movement and collision were interleaved, the order of events * would matter. By splitting movement and collision, the order of events does * not matter. * If an event can influence events of its type, this system won’t work. One * solution to this problem is to split the event in parts, that influence * each other but not themselves. */ // set vision for all players for (auto &player : players) { check_scan(player.second); } // Player Actions(Movement) for (auto &player : players) { player.second.update(); } // resolve Player Actions(Shooting) for (auto &player : players) { // see if any player wants to shoot if (player.second.shooting) { // reset the shooting flag player.second.shooting = false; // calculate the direction in which the Robot shoots double direction = player.second.getRotation() + player.second.getTurretAngle(); Vector_d porjectilePosition = player.second.getPosition(); // make sure we create the Projectile outside the player porjectilePosition += Vector_d::polar( direction, Vector_d(rules.robot_size.x, rules.projectile_size.x).magnitude()); // create the Projectile projectiles.push_back( Projectile(rules, porjectilePosition, direction, player.first)); } } // resolve Player collision for (auto &player : players) { // check collision between playeres // NOTE: currently we check each pair of players twice, once for // Collision(A,B) and once for Collision(B,A). for (auto const &player2 : players) { if (&player == &player2) { // don't check collision with self. continue; } if (Collision(player.second, player2.second)) { collisionSignal(player.first, player2.first); player.second.takeDamage(rules.collision_damage); } } } // resolve out-of-Bound events for (auto &player : players) { // check if any player is outside the arena Vector_d pos = player.second.getPosition(); if (pos.x > rules.arena_size.x || pos.y > rules.arena_size.y || pos.x < 0 || pos.y < 0) { outOfBoundsSignal(player.first); player.second.takeDamage(rules.collision_damage); } } // resolve collision between players and projectiles for (auto &player : players) { // check collision between player and projectile for (auto projectile = projectiles.begin(); projectile != projectiles.end();) { Collision collision(player.second, *projectile); if (collision) { // deal damage to the player player.second.takeDamage(rules.projectile_damage); hitSignal(player.first, projectile->owner); // remove projectile, and advance the iterator projectile = projectiles.erase(projectile); } else { // advance the iterator ++projectile; } } } }