void FlyingSaucerBoss::onUpdate(float frametime) { //Attack sf::Vector2f target_pos = m_target->getCenter(); m_left_tube.shoot(target_pos); m_right_tube.shoot(target_pos); if (getX() > CIRCLE_CENTER_X + CIRCLE_RADIUS) { move(-100 * frametime, 0); } else { sf::Vector2f pos(CIRCLE_CENTER_X, CIRCLE_CENTER_Y); m_angle += CIRCLE_ROTATION_SPEED * frametime; pos.x += CIRCLE_RADIUS * std::cos(m_angle); pos.y -= CIRCLE_RADIUS * std::sin(m_angle); setPosition(pos); } updateDamageFlash(frametime); m_timer += frametime; if (m_timer > 5.f) { m_timer = 0.f; EntityManager& em = EntityManager::getInstance(); Spaceship* mob = em.createSpaceship("s1"); mob->setPosition(getCenter()); em.addEntity(mob); } }
bool CollisionDetector::isLandingSuccessful() { GameObjectManager *gameObjManager = GameObjectManager::instance(); Spaceship *spaceship = gameObjManager->getSpaceship(); TerrainGenerator* terrainGenerator = TerrainGenerator::instance(); TerrainSegment* segment = terrainGenerator->getTerrainSegmentBasedOnX(spaceship->getXPosition()); if (typeid(LandingPad) != typeid(*segment)) { return false; } else { return landingSucceeds(spaceship); } }
bool CollisionDetector::spaceshipCrashWillHappen() { GameObjectManager *gameObjManager = GameObjectManager::instance(); Spaceship *spaceship = gameObjManager->getSpaceship(); TerrainGenerator* terrainGenerator = TerrainGenerator::instance(); TerrainSegment* segment = terrainGenerator->getTerrainSegmentBasedOnX(spaceship->getXPosition()); if (typeid(LandingPad) == typeid(*segment)) { bool softLanding = spaceship->getYSpeed() > landingSpeedLimit; bool withinLandingPad = segment->isSpaceshipWithinSegment(spaceship); return softLanding && withinLandingPad; } else { return collisionHappens(spaceship); } }
bool detect(Spaceship spaceship,Pattern pattern){ XPoint x1; XPoint x2; x1.x=spaceship.getX(); x2.x=spaceship.getX()+spaceship.getWidth(); x1.y=spaceship.getY()+spaceship.getHeight(); x2.y=spaceship.getY()+spaceship.getHeight(); line_function bottom(x1,x2); cout<<"spaceship at ("<<x1.x<<" , "<<x1.y<<endl; for(int i=0;i<pattern.lines.size();i++){ if(pattern.lines[i].intersect(bottom)){ return true; } } return false; }
void SpaceshipValidator::validate(const Spaceship & s) { string errors; if (s.getName().size() < 3) errors += string("The spaceship name cannot be less than 2 characters!\n"); if (!isupper(s.getCaptain()[0])) errors += string("The captain's name must start with a capital letter!\n"); if (s.getType().size() < 3) errors += string("The spaceship type cannot be less than 2 characters!\n"); if (errors.size() > 0) throw ValidationException(errors); /*if (errors.size() > 0) throw ValidationExceptionInherited(errors);*/ }
/*! * \fn void GameStd::shootPlayer(int playerNb) * \brief tire sur le joueur de numero passe en parametre et realise les actions consequentes * \param int playerNb le joueur sur lequel le tir a ete fait * \return */ void GameStd::shootPlayer(int playerNb){ SpaceshipFactory* factory = new SpaceshipFactoryStd(); Spaceship* s = players[playerNb]->getSpaceship(); //si Battlecruiser, l'artefact revient au shooter if (s->hasArtefact() && s->getType()==BattlecruiserType) players[currentPlayer]->getSpaceship()->takeArtefact(); //creation du nouveau vaisseau Spaceship* newSpaceship = factory->createNextSpaceship(s); //si Mothership, retour a la base if (newSpaceship->getType() == MothershipType){ GameBuilder* builder = new GameBuilderStd(); builder->setPosShip(newSpaceship,players[playerNb]->getColor(), getMapLongueur(), getMapHauteur()); delete builder; std::cout<<"remplacement par mothership"<<std::endl; } delete factory; players[playerNb]->replaceSpaceship(newSpaceship); std::cout << "Spaceship du joueur "<<playerNb<<"remplace"<<std::endl; }
void unittest () { unsigned short utCount = 5; unsigned short utPassed = 0; cout << "\nSTARTING UNIT TEST\n\n"; Spaceship enterprise; enterprise.setName("USS Enterprise"); try { btassert<bool>(enterprise.getName() == "USS Enterprise"); cout << "Passed TEST 1: setName/getName\n"; ++utPassed; } catch (bool b) { cout << "# FAILED TEST 1 setName/getName #\n"; } enterprise.setTopSpeed(9.6); try { btassert<bool>(enterprise.getTopSpeed() >= 9.59 && enterprise.getTopSpeed() <= 9.61); cout << "Passed TEST 2: setTopSpeed/getTopSpeed\n"; ++utPassed; } catch (bool b) { cout << "# FAILED TEST 2 setTopSpeed/getTopSpeed #\n"; } enterprise.setFuelSource("plasma"); try { btassert<bool>(enterprise.getFuelSource() == "plasma"); cout << "Passed TEST 3: setFuelSource/getFuelSource\n"; ++utPassed; } catch (bool b) { cout << "# FAILED TEST 3 setFuelSource/getFuelSource #\n"; } enterprise.setCrewCapacity(5000); try { btassert<bool>(enterprise.getCrewCapacity() == 5000); cout << "Passed TEST 4: setCrewCapacity/getCrewCapacity\n"; ++utPassed; } catch (bool b) { cout << "# FAILED TEST 4 setCrewCapacity/getCrewCapacity #\n"; } try { btassert<bool>(enterprise.toString() == "USS Enterprise, top speed: warp 9.60, fuel source: plasma, crew capacity: 5000"); cout << "Passed TEST 5: toString\n"; ++utPassed; } catch (bool b) { cout << "# FAILED TEST 5 toString #\n"; } cout << "\nUNIT TEST COMPLETE\n\n"; cout << "PASSED " << utPassed << " OF " << utCount << " UNIT TEST"; if (utCount > 1) { cout << "S"; } cout << "\n\n"; }
void operator() (Spaceship& spaceship, sf::Time) const { spaceship.accelerate(velocity * spaceship.getMaxSpeed()); }
// the main function, transferred in engine. Setting all the graphics stuff as children of Graphics and so on allowed me to make the functions slimmer int Engine::start(Pattern patt) { //int tmpx = 2, tmpy = 2; // For second plays cleanEnemyFleet(); cleanLasers(); lastTriggered = EVE_DEFAULT; // For intermediate animations. int intervalLaserCounter = 0; int turnCounter = 0; // For managing the laser shooting int lasercounter = 0; bool readyToFire = true; int passTurnTimer = 30; currentPattern = patt; // Getting the pointer straight protagonist = nullptr; expiredEnemy0 = false; expiredEnemy1 = false; //Start up SDL and create window // Here go all the things I need to start up the game. Eventually they'll get into a new nice function. // Main loop flag bool quit = false; // Event handler SDL_Event e; // Background color SDL_SetRenderDrawColor(graphEngine->getRenderer(), 255, 255, 255, 1); // Reminder of the last displayed Screens gLastDisplayed = MAIN_CAMERA; // Is there an enemy? enemyOnScreen = false; // First ship addProtagonist(); // The address of the enemy ship hit by lasers each turn Spaceship* hitTarget = nullptr; //First drawing SDL_RenderClear(graphEngine->getRenderer()); graphEngine->setView(MAIN_CAMERA); gLastDisplayed = MAIN_CAMERA; drawFleet(graphEngine); SDL_RenderPresent(graphEngine->getRenderer()); SDL_Delay(300); // TO DECUPLICATE while( !quit ) { // This is to achieve a nice stable framerate Uint32 time = SDL_GetTicks(); //Handle events on queue while (SDL_PollEvent (&e) != 0) { //User requests quit if (e.type == SDL_QUIT) { quit = true; } // User presses a key else if (e.type == SDL_KEYDOWN) { switch (e.key.keysym.sym) { case SDLK_x: { protagonist->setAtk(500); break; } case SDLK_n: { protagonist->setAtk(20); break; } case SDLK_ESCAPE: { quit = true; break; } default: break; } } // Things over this brace are only invoked at the press of a button } // Here I invoke the functions I need each time // This moves the ship on the position of the mouse. // Must start later int tX = 0, tY = 0; SDL_GetMouseState(&tX, &tY); // Ths avoids me going out of screen if (tX > SCREEN_WIDTH-40) { tX = SCREEN_WIDTH-40; } if (tX < 2) { tX = 2; } if (tY > SCREEN_HEIGHT-40) { tY = SCREEN_HEIGHT-40; } if (tY < 2) { tY = 2; } protagonist->teleport(tX, tY); // TODO: Regulate this treshold to achieve believable rate of fire if (!quit && intervalLaserCounter==3) { intervalLaserCounter = 1; if (lasercounter == 1) { lasercounter --; readyToFire = true; } else { lasercounter++; } } graphEngine->setView(gLastDisplayed); // These two are no longer troublesome graphEngine->printScore(score); graphEngine->printkills(kills); printHealth(); if (lastTriggered == GAME_LOST) { SDL_Delay(50); // TO DECUPLICATE quit = true; } else if (lastTriggered == MAIN_STAGE_CLEAR && currentPattern == MAIN_STAGE) { quit = true; } else if (lastTriggered == BOSS_STAGE_CLEAR && currentPattern == BOSS_STAGE) { quit = true; } if (readyToFire && enemyOnScreen) { // I shall make the count start from a certain turn readyToFire = false; // Contrarily to popular belief, lasers do NOT cause memory leaks. protagonistShootsSingleLaser(); //areLasersAimed = true; } nextMove(turnCounter, currentPattern, graphEngine); // Damaging enemies bool explosionPlayed = false; for (int i = 0; i<static_cast<int>(lasersOnMap.size()); i++) { hitTarget = nullptr; if (lasersOnMap[i]->isMFD()) { delete(lasersOnMap[i]); lasersOnMap.erase(lasersOnMap.begin()+i); if (!explosionPlayed) { Mix_PlayChannel(-1, graphEngine->getBoom(), 0); explosionPlayed = true; } } else if (lasersOnMap[i]->isHittingWall()) { delete(lasersOnMap[i]); lasersOnMap.erase(lasersOnMap.begin()+i); } else if (laserIsHittingTarget(i, hitTarget)) { if (hitTarget != nullptr){ hitTarget->takeDamage(lasersOnMap[i]->getPower()); if (!hitTarget->isAlive() && !hitTarget->isAllied()) { kills++; score += 500; explosion tmp = {static_cast<int>(hitTarget->getCenterX()), static_cast<int>(hitTarget->getCenterY()), 10}; kabooms.push_back(tmp); } lasersOnMap[i]->explode(); } hitTarget = nullptr; } } // Killing the enemy for (int i = 0; i<enemyFleet.size(); i++) { if (enemyOnScreen == true && enemyFleet[i]->getHP() <= 0) { hitTarget = nullptr; } } bool everyoneDead = true; for (int i = 0; i<enemyFleet.size(); i++) { if (enemyFleet[i]->isAlive()) { everyoneDead = false; } } if (everyoneDead) { enemyOnScreen = false; } //Adding points score += (SDL_GetTicks() - time); // Cleaning the lasers for (int i = 0; i<lasersOnMap.size(); i++) { //if (!areLasersAimed) { lasersOnMap[i]->travel(); //} // This is all in case I ever want to aim the lasers again /* else { if (lasersOnMap[i]->isSBA() && enemyOnScreen) { int x = 0, y = 0; coordsOfNearestEnemy(x, y, i, false); int cosfact = x - lasersOnMap[i]->getCentergX(); int sinfact = y - lasersOnMap[i]->getCentergY(); double targAngle; if (cosfact != 0) { targAngle = atan2(sinfact, cosfact); } else { if (sinfact > 0) { targAngle = pi/2; } else { targAngle = -pi/2; } } lasersOnMap[i]->setAngle(-targAngle); lasersOnMap[i]->travel(); } else { lasersOnMap[i]->travel(); } } */ } if (enemyFleet.size() == 0) { enemyOnScreen = false; } if (protagonist->getHP() <= 0) { setLastEvent(GAME_LOST); } if (turnCounter > 2000 && !enemyOnScreen && currentPattern == MAIN_STAGE) { if (passTurnTimer == 0) { cleanEnemyFleet(); cleanLasers(); setLastEvent(MAIN_STAGE_CLEAR); } else { passTurnTimer--; } } if (turnCounter > 20 && !enemyOnScreen && currentPattern == BOSS_STAGE) { if (passTurnTimer == 0) { cleanEnemyFleet(); cleanLasers(); setLastEvent(BOSS_STAGE_CLEAR); } else { passTurnTimer--; } } for (int i = 0; i<kabooms.size(); i++) { if (kabooms[i].timer == 0) { kabooms.erase(kabooms.begin()+i); } } for (int i = 0; i<kabooms.size(); i++) { OtherSprites fireball = rand() >= RAND_MAX/2 ? SHIP_EXPLODE_1 : SHIP_EXPLODE_2; double zF = (10-kabooms[i].timer); zF /= 10; graphEngine->printOtherOnScreen(fireball, kabooms[i].x, kabooms[i].y, 0, zF, 80, 80); kabooms[i].timer -= 1; } drawFleet(graphEngine); drawEnemyFleet(graphEngine); // Must render here else explosion will not be seen for (int i = 0; i<lasersOnMap.size(); i++) { lasersOnMap[i]->drawOnScreen(graphEngine); } /* SDL_SetRenderDrawColor(graphEngine->getRenderer(), 255, 0, 0, 0); SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect1); SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect2); SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect3); SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect4); */ intervalLaserCounter++; turnCounter++; SDL_RenderPresent(graphEngine->getRenderer()); if((1000/FPS)>(SDL_GetTicks()-time)) { SDL_Delay((1000/FPS)-(SDL_GetTicks()-time)); //SDL_Delay pauses the execution. } } // Here ends the main loop //Free resources and close SDL return 0; }
//This is my orthographic projection window with two viewports, one looking down the x and one down the z axis. void renderAxis() { vec3 position; glClearColor(0.4f, 0.4f, 0.4f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(globals.program2); //left side X-axis glViewport( (int)(.1*globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2) ); //Question //set view matrix with camera looking down x-axis glUniformMatrix4fv(globals.viewUniform2, 1, GL_FALSE, glm::value_ptr(globals.viewX)); //draw ships, save time and only draw one row, since in ortho proj we don't see anything behind since it's a parallel proj float coord[] = { -60.0f, -20.0f, 20.0f, 60.0f }; for(int i = 0; i < 4; i++) { position = vec3( 20.0f, 0.0f, coord[i]); ship.render(position, globals.vaoSphere2, globals.vaoCylinder2, globals.worldUniform2, globals.fragColorUniform2); } //draw sphere glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); //update uniforms mat4 temp(1.0f); temp[3] = vec4(-80.0f, 0.0f, 0.0f, 1.0f); glUniformMatrix4fv(globals.worldUniform2, 1, GL_FALSE, glm::value_ptr(temp)); vec4 color(1.0f, 1.0f, 1.0f, 1.0f); glUniform4fv(globals.fragColorUniform2, 1, glm::value_ptr(color)); glBindVertexArray(globals.vaoSphere3); glDrawElements(GL_TRIANGLES, globals.elementSphere3.size(), GL_UNSIGNED_SHORT, 0); //reset this so other objects get filled in glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); glBindVertexArray(0); //right side Z-axis glViewport( (int)(.1*globals.windowHalfWidth2 + globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2)); glUniformMatrix4fv(globals.viewUniform2, 1, GL_FALSE, glm::value_ptr(globals.viewZ)); for(int i = 0; i < 4; i++) { position = vec3( coord[i], 0.0f, 20.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); } //draw sphere glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); //update uniforms temp[3] = vec4(0.0f, 0.0f, -80.0f, 1.0f); glUniformMatrix4fv(globals.worldUniform2, 1, GL_FALSE, glm::value_ptr(temp)); color = vec4(1.0f, 1.0f, 1.0f, 1.0f); glUniform4fv(globals.fragColorUniform2, 1, glm::value_ptr(color)); glBindVertexArray(globals.vaoSphere3); glDrawElements(GL_TRIANGLES, globals.elementSphere3.size(), GL_UNSIGNED_SHORT, 0); glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); glBindVertexArray(0); glUseProgram(0); //draw frustum glUseProgram(globals.program3); glBindVertexArray(globals.vaoFrustum); //set uniforms that will be used by the frustum shader program mat4 world(1.0f); glUniformMatrix4fv(globals.worldUniform, 1, GL_FALSE, glm::value_ptr(world)); //world glUniformMatrix4fv(globals.viewUniform, 1, GL_FALSE, glm::value_ptr(globals.viewX)); //view glUniformMatrix4fv(globals.projUniform, 1, GL_FALSE, glm::value_ptr(globals.orthoProj)); //proj mat4 inverse = CalcViewMatrix(globals.camera.camPosition, globals.camera.camTarget, globals.camera.upDirection); inverse = glm::inverse(inverse); glUniformMatrix4fv(globals.inverseViewUniform, 1, GL_FALSE, glm::value_ptr(inverse)); // view inverse inverse = glm::inverse(globals.perspProj); glUniformMatrix4fv(globals.inverseProjUniform, 1, GL_FALSE, glm::value_ptr(inverse)); //proj inverse //use same two viewports for drawing the frustum. I do this separately because I have a particular shader program and didn't want to switch back and forth. //left side X-axis glViewport( (int)(.1*globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2) ); glPointSize(10.0f); glDrawElements(GL_LINES, 48, GL_UNSIGNED_SHORT, (GLvoid*)0); //right side Z-axis glUniformMatrix4fv(globals.viewUniform, 1, GL_FALSE, glm::value_ptr(globals.viewZ)); //view glViewport( (int)(.1*globals.windowHalfWidth2 + globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2)); glDrawElements(GL_LINES, 48, GL_UNSIGNED_SHORT, (GLvoid*)0); glBindVertexArray(0); glUseProgram(0); //draw text glViewport(0, 0, 400, 400); const unsigned char string1[] = "Options: w - wireframe mode, m - antialiasing, t - textures"; vec3 temp2(-80.0f, -30.0f, 0.0f); drawText(string1, temp2); const unsigned char string2[] = "X - A X I S"; temp2 = vec3(-80.0f, -40.0f, 0.0f); drawText(string2, temp2); glViewport(700, 0, 800, 400); const unsigned char string3[] = "Z - A X I S"; temp2 = vec3(-80.0f, -40.0f, 0.0f); drawText(string3, temp2); glutSwapBuffers(); glutPostRedisplay(); }
//This is my perspective window render fuction void renderFPS() { //enable options //msaa if(globals.msaaEnable) { glEnable(GL_MULTISAMPLE_ARB); } else { glDisable(GL_MULTISAMPLE_ARB); } //wireframe mode if(globals.wireframeEnable) { glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //get current view matrix from camera class mat4 view = CalcViewMatrix(globals.camera.camPosition, globals.camera.camTarget, globals.camera.upDirection); glUseProgram(globals.program1); //get view matrix from camera glUniformMatrix4fv(globals.viewUniform1, 1, GL_FALSE, glm::value_ptr(view)); //for this project, each ship is going to be the same, could either add method or parameter to pass in a "world" matrix //or a scale/rotation matrix to alter each ship individually //draw ships passing in the postion it should be placed float coord[] = { -60.0f, -20.0f, 20.0f, 60.0f }; //used to place ships vec3 position; for(int i = 0; i < 4; i++) { position = vec3( coord[i], 0.0f, -60.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); position = vec3( coord[i], 0.0f, -20.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); position = vec3( coord[i], 0.0f, 20.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); position = vec3( coord[i], 0.0f, 60.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); } glUseProgram(0); //I have this as an option since for this project we wanted to demonstrate the frustum and so I can't see all of the textured floor so I can //turn it on and off. if(globals.textureOn) { //draw textured floor glUseProgram(globals.programT); glBindVertexArray(globals.vaoT); glUniformMatrix4fv(globals.viewTUniform, 1, GL_FALSE, glm::value_ptr(view)); //view mat4 world(1.0f); world[3] = vec4(0.0f, -19.0f, 0.0f, 1.0f); //translate world[0].x = world[2].z = 100.0f; //scale glUniformMatrix4fv(globals.worldTUniform, 1, GL_FALSE, glm::value_ptr(world)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, globals.texture); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (GLubyte*)0); glBindVertexArray(0); glUseProgram(0); } //draw text glViewport(0, 0, 400, 400); //do this so that text gets rendered to same area in window and doesn't change due to resizing const unsigned char string1[] = "Options: w - wireframe mode, m - antialiasing, t - textures"; vec3 temp(-80.0f, -30.0f, 0.0f); drawText(string1, temp); const unsigned char string2[] = "PERSPECTIVE VIEW"; temp = vec3(-80.0f, -40.0f, 0.0f); drawText(string2, temp); glViewport(0, 0, globals.windowWidth1, globals.windowHeight1); //reset viewport back to entire screen glutSwapBuffers(); glutPostRedisplay(); }
/*This will setup Window 1 (perspective window). It loads and creates my shader programs, gets uniform handles, initializes all my vertex buffer objects and all my vertex array objects that will be used by the shaders. */ void init() { //set window dimensions //globals.windowWidth = 512; //globals.windowHeight = 512; //initialize spaceship ship.init(); //Initialize Programs GLuint vertShader, fragShader; vertShader = LoadShader(GL_VERTEX_SHADER, "D:/School/CS 559/Project 1/CS 559_Project 1/spaceship.vert"); fragShader = LoadShader(GL_FRAGMENT_SHADER, "D:/School/CS 559/Project 1/CS 559_Project 1/spaceship.frag"); globals.program1 = CreateProgram(vertShader, fragShader); //get uniforms globals.worldUniform1 = glGetUniformLocation(globals.program1, "worldMatrix"); globals.viewUniform1 = glGetUniformLocation(globals.program1, "viewMatrix"); globals.projUniform1 = glGetUniformLocation(globals.program1, "projMatrix"); globals.fragColorUniform1 = glGetUniformLocation(globals.program1, "Color"); //set uniforms glUseProgram(globals.program1); glUniformMatrix4fv(globals.projUniform1, 1, GL_FALSE, glm::value_ptr(globals.perspProj)); glUseProgram(0); //Floor program with textures vertShader = LoadShader(GL_VERTEX_SHADER, "D:/School/CS 559/Project 1/CS 559_Project 1/floor.vert"); fragShader = LoadShader(GL_FRAGMENT_SHADER, "D:/School/CS 559/Project 1/CS 559_Project 1/floor.frag"); globals.programT = CreateProgram(vertShader, fragShader); //get uniforms globals.worldTUniform = glGetUniformLocation(globals.programT, "worldMatrix"); globals.viewTUniform = glGetUniformLocation(globals.programT, "viewMatrix"); globals.projTUniform = glGetUniformLocation(globals.programT, "projMatrix"); globals.textureUniform = glGetUniformLocation(globals.programT, "floorSampler"); //set uniforms glUseProgram(globals.programT); glUniformMatrix4fv(globals.projTUniform, 1, GL_FALSE, glm::value_ptr(globals.perspProj)); glUseProgram(0); //Initialize Vertex Buffers //GeoSphere //position glGenBuffers(1, &globals.positionBufferSphere1); glBindBuffer(GL_ARRAY_BUFFER, globals.positionBufferSphere1); glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * ship.positionDataSphere.size(), (float*)ship.positionDataSphere.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); //indices glGenBuffers(1, &globals.elementBufferSphere1); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, globals.elementBufferSphere1); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLshort) * ship.indicesSphere.size(), (GLshort*)ship.indicesSphere.data(), GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //Cylinder //positoin glGenBuffers(1, &globals.positionBufferCylinder1); glBindBuffer(GL_ARRAY_BUFFER, globals.positionBufferCylinder1); glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * ship.positionDataCylinder.size(), (float*)ship.positionDataCylinder.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); //indices glGenBuffers(1, &globals.elementBufferCylinder1); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, globals.elementBufferCylinder1); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLshort) * ship.indicesCylinder.size(), (GLshort*)ship.indicesCylinder.data(), GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //VAO glGenVertexArrays(1, &globals.vaoSphere1); glBindVertexArray(globals.vaoSphere1); glBindBuffer(GL_ARRAY_BUFFER, globals.positionBufferSphere1); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, globals.elementBufferSphere1); glBindVertexArray(0); glGenVertexArrays(1, &globals.vaoCylinder1); glBindVertexArray(globals.vaoCylinder1); glBindBuffer(GL_ARRAY_BUFFER, globals.positionBufferCylinder1); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, globals.elementBufferCylinder1); glBindVertexArray(0); //Floor //position glGenBuffers(1, &globals.positionFloorBuffer); glBindBuffer(GL_ARRAY_BUFFER, globals.positionFloorBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * 4, (float*)globals.floor.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); //texture glGenBuffers(1, &globals.textureFloorBuffer); glBindBuffer(GL_ARRAY_BUFFER, globals.textureFloorBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * 4, (float*)globals.floorTex.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); //indices glGenBuffers(1, &globals.elementFloorBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, globals.elementFloorBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLshort) * 6, (GLshort*)globals.floorIndex, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); LoadTexture(); //vao glGenVertexArrays(1, &globals.vaoT); glBindVertexArray(globals.vaoT); glBindBuffer(GL_ARRAY_BUFFER, globals.positionFloorBuffer); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL); glBindBuffer(GL_ARRAY_BUFFER, globals.textureFloorBuffer); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, globals.elementFloorBuffer); glBindVertexArray(0); //Shapes are CCW for front facing triangles, either change this, or change the triangles/indices! glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW); //functions used to build shapes use counter clockwise as front facing! glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glDepthRange(0.0f, 1.0f); }
// EVENT LOOP!!!!!!!!!!!! void eventloop(XInfo& xinfo){ // add stuff to pain. listofd.push_front(&apolo); listofd.push_front(&Starter); listofd.push_front(&pattern); listofd.push_back(&Restarter); listofd.push_back(&Winner); listofd.push_back((&vertical)); listofd.push_back(&Horizontal); listofd.push_back(&leftHorizontal); listofd.push_back(&TopMeter); listofd.push_back((&EngineStats)); //listofd.push_front((&pattern)); XEvent event; KeySym key; char text[BufferSize]; unsigned long lastRepaint = 0; int xDiff=0; int yDiff=0; //infinite loop, enter q to exit. while (true) { if (XPending(xinfo.display)>0){ XNextEvent(xinfo.display, &event); //These are engine status. if(yDiff>=0){ vertical.currentSpeed=yDiff; } if(xDiff>=0){ Horizontal.currentSpeed=xDiff; } bool d = pattern.detect(apolo,pattern); if (xDiff<=0){ leftHorizontal.currentSpeed=abs(xDiff); } if (yDiff<=0){ TopMeter.currentSpeed=abs(yDiff); } //Here to make the driver complain. if (GameIsPlaying){ if(abs(xDiff)>=3||yDiff>4){ isGoingTooFast=true; } else {isGoingTooFast=false;} } //Here after the collision happen. if(d&&GameIsPlaying){ GameIsPlaying=!GameIsPlaying; if(yDiff>5){ IsSpeadTooMuch=true; } xDiff=0; yDiff=0; cout<<"position "<<apolo.getX()<<" "<<apolo.getY()<<endl; if(IsLandingOnPad&&(!IsSpeadTooMuch)){ Winner.hide=false; } else { Restarter.hide=false; } } switch (event.type) { /* * Exit when 'q' is typed. * Arguments for XLookupString : * event - the keyboard event * text - buffer into which text will be written * BufferSize - size of text buffer * key - workstation independent key symbol * 0 - pointer to a composeStatus structure */ case Expose: if(event.xexpose.count ==0){ printf("Expose event recieved. Redrawing\n"); repaint(xinfo); } break; case KeyPress: int i =XLookupString((XKeyEvent*)&event, text, BufferSize, &key, 0 ); cout << "KeySym " << key << " text='" << text << "'" << " at " << event.xkey.time << endl; //press q to exit if ( i == 1 && text[0] == 113 ) { cout << "Terminated normally." << endl; // XCloseDisplay(xinfo.display); return; } //UP key if ( key == XK_Up ) { cout << "[Up]" << endl; if(GameIsPlaying&&yDiff>=-2){ yDiff-=1; } } //Down Key if ( key == XK_Down ) { cout << "[D]" << endl; if (GameIsPlaying&&(yDiff<=10)){ yDiff=yDiff+1; } } //Left key if ( key == XK_Left ) { cout << "[L]" << endl; if (GameIsPlaying&&(xDiff>=-10)){ xDiff=xDiff-1; } } //Right key if ( key == XK_Right ) { cout << "[D]" << endl; if((xDiff<=10)&&GameIsPlaying){ xDiff+=1; } } //Space if ( i == 1 && text[0] == 32 ) { cout << "[ ]" << endl; GameIsPlaying=!GameIsPlaying; Starter.hide=true; if(d){ apolo=Spaceship(10,10); Restarter.hide=true; if(IsLandingOnPad){ Winner.hide=true; } if(IsSpeadTooMuch){ IsSpeadTooMuch=false; } IsLandingOnPad=false; } } break; } } //cout<<"aaaa"<<endl; //Handle key press done, now do the drawing unsigned long end = now(); if (end - lastRepaint > 1000000/FPS) { if (GameIsPlaying){ handleDoubleBuffer(xinfo, xDiff, yDiff); } repaint(xinfo); lastRepaint = now(); } else if (XPending(xinfo.display) == 0) { usleep(1000000/FPS - (end - lastRepaint)); } } }
/*move the ship */ void handleDoubleBuffer(XInfo &xinfo, int xDiff, int yDiff) { apolo.move(xinfo, xDiff, yDiff); }
void Flocking::Update(float elapsedTime) { // array of pointers to aliens Flocking** alien = new Flocking*[alienNo]; bool direction = true; // load spaceship Spaceship* spaceship = dynamic_cast<Spaceship*>(Game::GetGameObjectsManager().Get(0)); sf::Vector2f spaceshipPos; if(spaceship != NULL) { spaceshipPos = spaceship->GetPosition(); sf::Rect<float> spaceshipBounds = spaceship->GetBoundingRect(); if(spaceshipBounds.intersects(GetBoundingRect())) { //(GetPosition().x + moveByX + (GetSprite().GetSize().x /2),GetPosition().y + (GetSprite().GetSize().y /2) + moveByY)) spaceship->reduceHealth(1); } int middleAlienInt = alienNo/2 +1; // middle alien movement if (alienNo < 3){ middleAlienInt = 1; } alien[middleAlienInt] = dynamic_cast<Flocking*>(Game::GetGameObjectsManager().Get(middleAlienInt)); sf::Vector2f middleAlienPos = alien[middleAlienInt]->GetPosition(); // position vector // head towards spaceship float dirx = (spaceshipPos.x - middleAlienPos.x); float diry = (spaceshipPos.y - middleAlienPos.y); // initial velocity sf::Vector2f velocityMidd(dirx, diry); // initial acceleration sf::Vector2f accelerationV(0.0f, 0.0f); sf::Vector2f separationV(0.0f, 0.0f); int neighbourCount = 0; int index = 1; int index2 = 1; //#pragma omp for schedule(static) ordered //#pragma omp parallel //#pragma omp for firstprivate(index2) lastprivate(index) #pragma omp parallel for schedule(dynamic, alienNo+1) ordered firstprivate(index2) lastprivate(index) // alien group movement for (index = 1 ; index < alienNo+1 ; index++) { alien[index] = dynamic_cast<Flocking*>(Game::GetGameObjectsManager().Get(index)); sf::Vector2f currentAlienPos = alien[index]->GetPosition(); // head towards middle spaceship float dirx = (middleAlienPos.x - currentAlienPos.x); float diry = (middleAlienPos.y - currentAlienPos.y); // initial velocity sf::Vector2f velocityGroup(dirx, diry);//(dirx+100, diry+100); sf::Vector2f velocityDiff(dirx, diry); sf::Vector2f velocitySepp(0.0f, 0.0f); // alignment & cohesion - line up & steer towards average position of neibours for (index2 = 1 ; index2 < alienNo+1 ; index2++) { if (index != index2) {//&& middleAlienInt != index2) { alien[index2] = dynamic_cast<Flocking*>(Game::GetGameObjectsManager().Get(index2)); sf::Vector2f nextAlienPos = alien[index2]->GetPosition(); // Calculate the difference between the two objects. sf::Vector2f differenceV = currentAlienPos - nextAlienPos; float distance1 = sqrt(differenceV.x*differenceV.x + differenceV.y*differenceV.y); // check for nearby aliens and steer towards them float neighbourDist = 100; if (neighbourCount == 0) velocityGroup = velocityCurr; // Check of the objects are closer that the collision distance. if (distance1 < neighbourDist) { neighbourCount++; // Calculate the difference between the two objects. sf::Vector2f differenceV2 = middleAlienPos - currentAlienPos; //float distance = sqrt(differenceV2.x*differenceV2.x + differenceV2.y*differenceV2.y); // when a neighbor is found, the position of the neighbour is added to the vector velocityGroup.x += (velocityCurr.x + differenceV2.x)*index*maxSpeed; velocityGroup.y += (velocityCurr.y + differenceV2.y)*index*maxSpeed; velocityGroup.x /= neighbourCount; velocityGroup.y /= neighbourCount; float separation = 40; // Check of the objects are closer that the collision distance. if (distance1 < separation) { velocitySepp.x = currentAlienPos.x - nextAlienPos.x; velocitySepp.y = currentAlienPos.y - nextAlienPos.y; direction = false; } } } } velocityGroup += accelerationV*elapsedTime; if (((velocityGroup.x*velocityGroup.x)+(velocityGroup.y*velocityGroup.y))>maxSpeed*maxSpeed) { velocityGroup = Flocking::Normalize(velocityGroup); velocityGroup *= maxSpeed; } velocityDiff += accelerationV*elapsedTime; if (((velocityDiff.x*velocityDiff.x)+(velocityDiff.y*velocityDiff.y))>maxSpeed*maxSpeed) { velocityDiff = Flocking::Normalize(velocityDiff); velocityDiff *= maxSpeed; } if(direction == false && index != middleAlienInt) { velocityGroup = velocitySepp; velocityGroup += accelerationV*elapsedTime; velocityGroup *= -1.0f; if (((velocityGroup.x*velocityGroup.x)+(velocityGroup.y*velocityGroup.y))>maxSpeed*maxSpeed) { velocityGroup = Flocking::Normalize(velocityGroup); velocityGroup *= maxSpeed; } velocityGroup += velocityDiff; velocityGroup *= -1.0f; } if(direction == false && index == middleAlienInt) { velocityMidd += accelerationV*elapsedTime; if (((velocityMidd.x*velocityMidd.x)+(velocityMidd.y*velocityMidd.y))>maxSpeed*maxSpeed) { velocityMidd = Flocking::Normalize(velocityMidd); velocityMidd *= maxSpeed; } } else { velocityMidd += accelerationV*elapsedTime; if (((velocityMidd.x*velocityMidd.x)+(velocityMidd.y*velocityMidd.y))>maxSpeed*maxSpeed) { velocityMidd = Flocking::Normalize(velocityMidd); velocityMidd *= maxSpeed; } } //#pragma omp ordered alien[middleAlienInt]->SetPosition(middleAlienPos.x + velocityMidd.x*elapsedTime/alienNo, middleAlienPos.y + velocityMidd.y*elapsedTime/alienNo); //printf("\n"); if (index != middleAlienInt) { alien[index]->SetPosition(currentAlienPos.x + (velocityGroup.x)*elapsedTime/alienNo + (velocityDiff.x)*elapsedTime/alienNo, currentAlienPos.y + (velocityGroup.y)*elapsedTime/alienNo + (velocityDiff.y)*elapsedTime/alienNo); } } } }
/* * Name : lab_9_unit_test.cpp * Author : Luke Sathrum * Description : Unit test to test Lab #9 Functionality */ #define CATCH_CONFIG_MAIN #include "catch.hpp" #include "lab_9.h" TEST_CASE("Creating a Spaceship") { Spaceship enterprise; enterprise.set_name("USS Enterprise-D"); SECTION("set_name(\"USS Enterprise-D\")/name()") { CHECK(enterprise.name() == "USS Enterprise-D"); } enterprise.set_top_speed(9.6); SECTION("set_top_speed(9.6)/top_speed()") { CHECK(enterprise.top_speed() >= 9.59); CHECK(enterprise.top_speed() <= 9.61); } enterprise.set_fuel_source("Plasma"); SECTION("set_fuel_source(\"Plasma\")/fuel_source()") { CHECK(enterprise.fuel_source() == "Plasma"); } enterprise.set_crew_capacity(5000); SECTION("set_crew_capacity(5000)/crew_capacity()") {