void SampleSubmarine::onSubstepStart(float dtime) { // kick off crab updates in parallel to simulate const size_t nbCrabs = mCrabs.size(); for(PxU32 i = 0; i < nbCrabs; i++) { Crab* crab = mCrabs[i]; crab->removeReference(); } }
void SampleSubmarine::onSubstepSetup(float dt, pxtask::BaseTask* completionTask) { // set Crabs continuation to ensure the completion task // is not run before Crab update has completed const size_t nbCrabs = mCrabs.size(); for(PxU32 i = 0; i < nbCrabs; i++) { Crab* crab = mCrabs[i]; crab->update(dt); crab->setContinuation(completionTask); } }
void Game::doAI() { for(int i = 1; i < 4; i++) { Crab* crab = crabs0[i]; if (crab == NULL) { continue; } //Find the position of the ball that is nearest the crab's side, and //store the result in targetPos float closestBallDist = 100; float targetPos = 0.5f; for(unsigned int j = 0; j < balls0.size(); j++) { Ball* ball = balls0[j]; float ballDist; float ballPos; switch(i) { case 1: ballDist = ball->x() - ball->radius(); ballPos = 1 - ball->z(); break; case 2: ballDist = 1 - ball->z() - ball->radius(); ballPos = 1 - ball->x(); break; case 3: ballDist = 1 - ball->x() - ball->radius(); ballPos = ball->z(); break; } if (ballDist < closestBallDist) { targetPos = ballPos; closestBallDist = ballDist; } } //Move toward targetPos. Stop so that the ball is in the middle 70% of //the crab. if (abs(stopPos(crab) - targetPos) < 0.7f * (CRAB_LENGTH / 2)) { crab->setDir(0); } else if (targetPos < crab->pos()) { crab->setDir(-1); } else { crab->setDir(1); } } }
int main(){ using namespace std; Crab<Stack> nebula; int ni; double nb; cout << "enter int double pairs, such an 4 3.5 (0 0 to end):\n"; while(cin >> ni >> nb && ni > 0 && nb > 0){ if(!nebula.push(ni,nb)) break; } while(nebula.pop(ni,nb)) cout << ni << ", " << nb << endl; cout << "done!\n"; return 0; }
int main(void) { using std::cout; using std::cin; using std::endl; Crab<Stack> nebula; //Stack must match template<typename T> class Thing int ni; double nb; cout << "Enter int double pairs, such as 4 3.5 (0 0 to be end):\n"; while(cin >> ni >> nb && ni > 0 && nb > 0) { if(!nebula.push(ni,nb)) break; } while(nebula.pop(ni,nb)) cout << ni << ", " << nb << endl; cout << "Done.\n"; return 0; }
void GameDrawer::drawCrabsAndPoles(bool isReflected) { if (crabModel != NULL) { glEnable(GL_NORMALIZE); for(int i = 0; i < 4; i++) { Crab* crab = game->crabs()[i]; //Translate and rotate to the appropriate side of the board glPushMatrix(); switch(i) { case 1: glTranslatef(0, 0, 1); glRotatef(90, 0, 1, 0); break; case 2: glTranslatef(1, 0, 1); glRotatef(180, 0, 1, 0); break; case 3: glTranslatef(1, 0, 0); glRotatef(270, 0, 1, 0); break; } if (crab != NULL || crabFadeAmounts[i] > 0) { //Draw the crab glPushMatrix(); float crabPos; if (crab != NULL) { crabPos = crab->pos(); } else { crabPos = oldCrabPos[i]; } glTranslatef(crabPos, 0.055f, CRAB_OFFSET); if (crab == NULL) { //Used for the shrinking effect, whereby crabs shrink //until they disappear when they are eliminated from play glTranslatef(0, -0.055f * (1 - crabFadeAmounts[i]), 0); glScalef(crabFadeAmounts[i], crabFadeAmounts[i], crabFadeAmounts[i]); } glRotatef(-90, 0, 1, 0); glRotatef(-90, 1, 0, 0); glScalef(0.05f, 0.05f, 0.05f); if (crab == NULL || crab->dir() == 0) { crabModel->setAnimation("stand"); } else { crabModel->setAnimation("run"); } glColor3f(1, 1, 1); crabModel->draw(i, animTimes[i]); glPopMatrix(); } if (crab == NULL) { //Draw the pole if (isReflected) { glDisable(GL_NORMALIZE); } glCallList(poleDisplayListId); if (isReflected) { glEnable(GL_NORMALIZE); } } glPopMatrix(); } } }
void GameDrawer::step() { //Advance the game game->advance(STEP_TIME); //Advance the water waterTextureOffset += STEP_TIME / WATER_TEXTURE_TIME; while (waterTextureOffset > WATER_TEXTURE_SIZE) { waterTextureOffset -= WATER_TEXTURE_SIZE; } //Update animTimes, crabFadeAmounts, and isGameOver0 bool opponentAlive = false; for(int i = 0; i < 4; i++) { Crab* crab = game->crabs()[i]; if (crab != NULL) { oldCrabPos[i] = crab->pos(); } //Update animation time if (crab != NULL || crabFadeAmounts[i] > 0) { if (crab != NULL && crab->dir() != 0) { if (crab->dir() > 0) { animTimes[i] += STEP_TIME / WALK_ANIM_TIME; } else { animTimes[i] -= STEP_TIME / WALK_ANIM_TIME; } } else { animTimes[i] += STEP_TIME / STAND_ANIM_TIME; } while (animTimes[i] > 1) { animTimes[i] -= 1; } while (animTimes[i] < 0) { animTimes[i] += 1; } } //Update fade amount if (crab == NULL) { crabFadeAmounts[i] -= STEP_TIME / CRAB_FADE_OUT_TIME; if (crabFadeAmounts[i] < 0) { if (i == 0) { isGameOver0 = true; } crabFadeAmounts[i] = 0; } else if (i != 0) { opponentAlive = true; } } else if (i != 0) { opponentAlive = true; } } if (!opponentAlive) { isGameOver0 = true; } }
void Game::step() { //Advance the crabs for(int i = 0; i < 4; i++) { Crab* crab = crabs0[i]; if (crab != NULL) { crab->advance(GAME_STEP_TIME); } } //Advance the balls for(unsigned int i = 0; i < balls0.size(); i++) { balls0[i]->advance(GAME_STEP_TIME); } //Handle collisions handleCollisions(); //Check for balls that have scored on a player vector<Ball*> newBalls; for(unsigned int i = 0; i < balls0.size(); i++) { Ball* ball = balls0[i]; if (ball->fadeAmount() == 1 && !ball->isFadingOut()) { newBalls.push_back(ball); int scoredOn; if (ball->z() < ball->radius() && (ball->angle() > PI)) { scoredOn = 0; } else if (ball->x() < ball->radius() && (ball->angle() > PI / 2 && ball->angle() < 3 * PI / 2)) { scoredOn = 1; } else if (ball->z() > 1 - ball->radius() && (ball->angle() < PI)) { scoredOn = 2; } else if (ball->x() > 1 - ball->radius() && (ball->angle() < PI / 2 || ball->angle() > 3 * PI / 2)) { scoredOn = 3; } else { scoredOn = -1; } if (scoredOn >= 0 && crabs0[scoredOn] != NULL) { scores[scoredOn]--; if (scores[scoredOn] == 0) { delete crabs0[scoredOn]; crabs0[scoredOn] = NULL; } ball->fadeOut(); } } else if (ball->fadeAmount() > 0 || !ball->isFadingOut()) { newBalls.push_back(ball); } else { delete ball; } } balls0 = newBalls; //Check whether the game is over bool isGameOver; if (crabs0[0] != NULL) { isGameOver = true; for(int i = 1; i < 4; i++) { if (crabs0[i] != NULL) { isGameOver = false; } } } else { isGameOver = true; } if (!isGameOver) { //Try to get to NUM_BALLS balls while (balls0.size() < (unsigned int)NUM_BALLS) { //Try to place a ball at the center of the board bool ballFits = true; for(unsigned int i = 0; i < balls0.size(); i++) { Ball* ball = balls0[i]; if (intersectsCircle(ball->x() - 0.5f, ball->z() - 0.5f, 2 * BALL_RADIUS)) { ballFits = false; break; } } if (ballFits) { Ball* ball = new Ball(BALL_RADIUS, 0.5f, 0.5f, 2 * PI * randomFloat()); balls0.push_back(ball); } else { break; } } } else { for(unsigned int i = 0; i < balls0.size(); i++) { balls0[i]->fadeOut(); } } //Run the AI for the computer-controlled crabs doAI(); }
void SampleSubmarine::onTickPreRender(float dtime) { // handle mine (and submarine) explosion if(mSubmarineActor) { // explode all touched mines, apply damage and force to submarine PxVec3 subMarinePos = mSubmarineActor->getGlobalPose().p; const size_t nbExplodeSeamines = mMinesToExplode.size(); for(PxU32 i=0; i < nbExplodeSeamines; i++) { Seamine* mine = mMinesToExplode[i]; PxVec3 explosionPos = mine->mMineHead->getGlobalPose().p; // disable contact trigger callback of the chain & enable gravity const size_t nbLinks = mine->mLinks.size(); for(PxU32 j = 0; j < nbLinks; j++) { PxRigidDynamic* link = mine->mLinks[j]; setupFiltering(link, 0, 0); link->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false); } // remove mine head std::vector<Seamine*>::iterator mineIter = std::find(mSeamines.begin(), mSeamines.end(), mine); if(mineIter != mSeamines.end()) mSeamines.erase(mineIter); removeActor(mine->mMineHead); delete mine; // give damage to submarine static const PxReal strength = 400.0f; PxVec3 explosion = subMarinePos - explosionPos; PxReal len = explosion.normalize(); PxReal damage = strength * (1.0f/len); explosion *= damage; mSubmarineActor->addForce(explosion*300); gSubmarineHealth = PxMax(gSubmarineHealth-PxI32(damage), 0); if(gSubmarineHealth == 0) { mSubmarineCameraController->init(subMarinePos - getCamera().getViewDir()*10.0f, getCamera().getRot()); explode(mSubmarineActor, subMarinePos /*- explosion*0.2f*/, damage); mCameraAttachedToActor = NULL; mSubmarineCameraController->setFollowingMode(false); mSubmarineActor = NULL; break; } } mMinesToExplode.clear(); } // respawn Crabs const size_t nbCrabs = mCrabs.size(); for(PxU32 i = 0; i < nbCrabs; i++) { Crab* crab = mCrabs[i]; if(crab->needsRespawn()) { PxRigidDynamic* prevBody = crab->getCrabBody(); PxVec3 prevPos = prevBody->getGlobalPose().p; delete crab; mCrabs[i] = SAMPLE_NEW(Crab)(*this, prevPos, mManagedMaterials[MATERIAL_RED]); if(gCrab == crab) gCrab = mCrabs[i]; if(mCameraAttachedToActor == prevBody) mCameraAttachedToActor = mCrabs[i]->getCrabBody(); } } // update camera if(mCameraAttachedToActor) mSubmarineCameraController->updateFollowingMode(getCamera(), dtime, mCameraAttachedToActor->getGlobalPose().p); // start the simulation PhysXSample::onTickPreRender(dtime); }