#include "MultiGame.h" #include "../CSC8503Common/GameWorld.h" #include "../../Plugins/OpenGLRendering/OGLMesh.h" #include "../../Plugins/OpenGLRendering/OGLShader.h" #include "../../Plugins/OpenGLRendering/OGLTexture.h" #include "../../Common/TextureLoader.h" #include "../CSC8503Common/PositionConstraint.h" #include "../CSC8503Common/HingeConstraint.h" #include "../CSC8503Common/FixedHeightConstraint.h" #include <string> using namespace NCL; using namespace CSC8503; MultiGame::MultiGame(int enemies) { world = new GameWorld(); renderer = new GameTechRenderer(*world); physics = new PhysicsSystem(*world); forceMagnitude = 100.0f; useGravity = true; inSelectionMode = false; numberOfEnemies = enemies; Debug::SetRenderer(renderer); InitialiseAssets(); } void MultiGame::InitialiseAssets() { auto loadFunc = [](const string& name, OGLMesh** into) { *into = new OGLMesh(name); (*into)->SetPrimitiveType(GeometryPrimitive::Triangles); (*into)->UploadToGPU(); }; loadFunc("cube.msh", &cubeMesh); loadFunc("sphere.msh", &sphereMesh); loadFunc("Male1.msh", &charMeshA); loadFunc("courier.msh", &charMeshB); loadFunc("security.msh", &enemyMesh); loadFunc("coin.msh", &bonusMesh); loadFunc("capsule.msh", &capsuleMesh); basicTex = (OGLTexture*)TextureLoader::LoadAPITexture("checkerboard.png"); basicShader = new OGLShader("GameTechVert.glsl", "GameTechFrag.glsl"); InitCamera(); InitWorld(); } MultiGame::~MultiGame() { delete cubeMesh; delete sphereMesh; delete charMeshA; delete charMeshB; delete enemyMesh; delete bonusMesh; delete basicTex; delete basicShader; delete physics; delete renderer; delete world; } void MultiGame::DisplayGrid() { NavigationGrid grid("LevelMulti1.txt"); for (int i = 0; i < grid.GetNodeCount(); i++) { for (int j = 0; j < 4; j++) { if (grid.GetNodes()[i].connected[j]) { renderer->DrawLine(grid.GetNodes()[i].position + Vector3(0, 1, 0), grid.GetNodes()[i].connected[j]->position + Vector3(0, 1, 0), Vector4(0, 0.0, 1.0, 1)); } } } } void MultiGame::UpdateGame(float dt) { EndGame(dt); if (levelCompleted == false) { endGameTimer += dt; if (endGameTimer >= 1.0f) { endGameTimer = 0.0f; playerCharacter->SetScore(playerCharacter->GetScore() - 10); } levelTimer += dt; //Restart position of a falling player if (playerCharacter->GetTransform().GetPosition().y <= -10) { playerCharacter->GetTransform().SetPosition(Vector3(0, 1, 30)); } if (!inSelectionMode) { world->GetMainCamera()->UpdateCamera(dt); } CameraMovement(); UpdateKeys(dt); MovePlayerCharacter(dt); MoveEnemies(dt); // SelectObject(); } physics->Update(dt); world->UpdateWorld(dt); renderer->Update(dt); renderer->Render(); //Display AI pathfinding grid if (toggleGrid) { DisplayGrid(); } DrawDisplay(dt); } void MultiGame::UpdateKeys(float dt) { //if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::F1)) { // InitWorld(); //We can reset the simulation at any time with F1 // //selectionObject = nullptr; // lockedObject = nullptr; // levelTimer = 0.0f; //} if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::F2)) { InitCamera(); //F2 will reset the camera to a specific default place } if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::G)) { useGravity = !useGravity; //Toggle gravity! physics->UseGravity(useGravity); } //Running certain physics updates in a consistent order might cause some //bias in the calculations - the same objects might keep 'winning' the constraint //allowing the other one to stretch too much etc. Shuffling the order so that it //is random every frame can help reduce such bias. if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::F9)) { world->ShuffleConstraints(true); } if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::F10)) { world->ShuffleConstraints(false); } if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::F7)) { world->ShuffleObjects(true); } if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::F8)) { world->ShuffleObjects(false); } if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::L)) { toggleGrid = !toggleGrid; } } void MultiGame::CameraMovement() { Vector3 objPos = playerCharacter->GetTransform().GetPosition(); Vector3 camPos = objPos + playerCharacter->GetTransform().GetOrientation() * lockedOffset; Matrix4 temp = Matrix4::BuildViewMatrix(camPos, objPos + Vector3(0, 5, 0), Vector3(0, 1, 0)); Matrix4 modelMat = temp.Inverse(); Quaternion q(modelMat); Vector3 angles = q.ToEuler(); world->GetMainCamera()->SetPosition(camPos); world->GetMainCamera()->SetPitch(angles.x); world->GetMainCamera()->SetYaw(angles.y); } void MultiGame::MovePlayerCharacter(float dt) { float rotationSpeed = 60.0f; Vector3 pyr = playerCharacter->GetTransform().GetOrientation().ToEuler(); if (Window::GetKeyboard()->KeyDown(KeyboardKeys::W)) { playerCharacter->SetSleep(false); playerCharacter->GetPhysicsObject()->AddForce(playerCharacter->GetTransform().GetOrientation() * Vector3(0, 0, -1) * forceMagnitude * playerCharacter->GetSpeedMultiplier()); } if (Window::GetKeyboard()->KeyDown(KeyboardKeys::A)) { playerCharacter->SetSleep(false); pyr.y += rotationSpeed * dt; pyr.y = pyr.y >= 0.0f ? pyr.y <= 360.0f ? pyr.y : pyr.y - 360.0f : pyr.y + 360.0f; playerCharacter->GetTransform().SetOrientation(Quaternion::EulerAnglesToQuaternion(pyr.x, pyr.y, pyr.z)); } if (Window::GetKeyboard()->KeyDown(KeyboardKeys::S)) { playerCharacter->SetSleep(false); playerCharacter->GetPhysicsObject()->AddForce(playerCharacter->GetTransform().GetOrientation() * Vector3(0, 0, 1) * forceMagnitude * playerCharacter->GetSpeedMultiplier()); } if (Window::GetKeyboard()->KeyDown(KeyboardKeys::D)) { playerCharacter->SetSleep(false); pyr.y -= rotationSpeed * dt; pyr.y = pyr.y >= 0.0f ? pyr.y <= 360.0f ? pyr.y : pyr.y - 360.0f : pyr.y + 360.0f; playerCharacter->GetTransform().SetOrientation(Quaternion::EulerAnglesToQuaternion(pyr.x, pyr.y, pyr.z)); } if (Window::GetKeyboard()->KeyDown(KeyboardKeys::SPACE)) { playerCharacter->SetSleep(false); //if (jumpTimer <= 0.0) { playerCharacter->GetPhysicsObject()->AddForce(Vector3(0, 2, 0) * forceMagnitude); jumpTimer += 2.0f; // } } } void MultiGame::MoveEnemies(float dt) { for (int i = 0; i < enemies.size(); i++) { enemies[i]->UpdatePosition(dt); } } void MultiGame::InitCamera() { world->GetMainCamera()->SetNearPlane(0.5f); world->GetMainCamera()->SetFarPlane(2000.0f); world->GetMainCamera()->SetPitch(-15.0f); world->GetMainCamera()->SetYaw(315.0f); world->GetMainCamera()->SetPosition(Vector3(-60, 40, 60)); lockedObject = nullptr; } void MultiGame::InitWorld() { world->ClearAndErase(); physics->Clear(); forceMagnitude = 50.0f; obstacles.clear(); //movables.clear(); //movableDoors.clear(); //obstacleDoors.clear(); //obstacleMaze.clear(); bonus.clear(); //Setup Vector3 floorPosition(0, -2, 0); Vector3 floorSize(125, 2, 125); Vector3 wallSize(2, 50, 500); Vector4 floorColour(1, 1, 1, 1); Vector4 terrainColour(0, 0, 1, 1); //Player Starting Position playerCharacter = AddPlayerToWorld(Vector3(20,1,30)); // playerCharacter = AddPlayerToWorld(Vector3(0, 1, -65)); //Player First save point //playerCharacter = AddPlayerToWorld(Vector3(0, 9, -257)); //Player Second save point //playerCharacter = AddPlayerToWorld(Vector3(0, 9, -315)); //playerCharacter = AddPlayerToWorld(Vector3(0, 9, -430)); //playerCharacter->AddScore(1000); playerCharacter->AddScore(1000); for (int i = 0; i < numberOfEnemies; ++i) { AddAIOpponentToWorld(Vector3((10 * i) - 100, 1, -30)); //Enemies - //x115 - 10 / z100 //player x115 z110 } //Wall Right obstacles.push_back(AddCubeToWorld(Vector3(125,2,0), Vector3(1, floorSize.y, floorSize.z), 0.0f)); // Wall Left obstacles.push_back(AddCubeToWorld(Vector3(-125, 2, 0), Vector3(1, floorSize.y, floorSize.z), 0.0f)); //Wall Bottom obstacles.push_back(AddCubeToWorld(Vector3(0, 2, 125), Vector3(floorSize.z, floorSize.y, 1), 0.0f)); //Wall Up obstacles.push_back(AddCubeToWorld(Vector3(0, 2, -125), Vector3(floorSize.z, floorSize.y, 1), 0.0f)); //Add starting location AddFloorToWorld(floorPosition, floorSize, floorColour, CollisionResolution::Impulse); //Add starting Constraint obstacle //Left obstacles.push_back(AddCubeToWorld(Vector3(-50, 3, -80), Vector3(70, 3, 1), 0.0f)); //Right obstacles.push_back(AddCubeToWorld(Vector3(75, 3, -80), Vector3(50, 3, 1), 0.0f)); obstacles.push_back(AddCubeToWorld(Vector3(85, 3, -70), Vector3(40, 3, 3), 0.0f)); obstacles.push_back(AddCubeToWorld(Vector3(95, 3, -60), Vector3(30, 3, 3), 0.0f)); obstacles.push_back(AddCubeToWorld(Vector3(65, 3, -40), Vector3(60, 3, 3), 0.0f)); obstacles.push_back(AddCubeToWorld(Vector3(65, 3, -50), Vector3(60, 3, 3), 0.0f)); obstacles.push_back(AddCubeToWorld(Vector3(45, 3, -30), Vector3(80, 3, 3), 0.0f)); obstacles.push_back(AddCubeToWorld(Vector3(85, 3, -20), Vector3(40, 3, 3), 0.0f)); //Non passable object with Contraints (Position, Hinge and Height) AddFinishGateToWorld(Vector3(-12, 8, -100), Vector3(0, 0, 0)); //Enemies //AddAIOpponentToWorld(Vector3(100, 1, -30)); //AddAIOpponentToWorld(Vector3(95, 1, -30)); //AddAIOpponentToWorld(Vector3(90, 1, -30)); ////bonus.push_back(AddBonusToWorld(Vector3(100, 1, -30))); //bonus.push_back(AddBonusToWorld(Vector3(1, 2, -23))); //bonus.push_back(AddBonusToWorld(Vector3(0, 2, -60))); //bonus.push_back(AddBonusToWorld(Vector3(0, 2, -80))); //bonus.push_back(AddBonusToWorld(Vector3(0, 2, -100))); } void MultiGame::EndGame(float dt) { if (playerCharacter->GetTransform().GetPosition().z <= -100) { DrawDisplay(dt); renderer->DrawString("You have won", Vector2(45, 50)); renderer->DrawString("Press Enter/Return to go back to menu", Vector2(20, 60)); levelCompleted = true; playerCharacter->MakeInactive(); if (Window::GetKeyboard()->KeyDown(KeyboardKeys::RETURN)) { gameFinished = true; } } for (int i = 0; i < enemies.size(); ++i) { if (enemies[i]->GetTransform().GetPosition().z <= -100) { DrawDisplay(dt); renderer->DrawString("You have lost", Vector2(45, 50)); renderer->DrawString("Press Enter/Return to go back to main menu", Vector2(20, 60)); levelCompleted = true; playerCharacter->MakeInactive(); if (Window::GetKeyboard()->KeyDown(KeyboardKeys::RETURN)) { gameFinished = true; } } } } GameObject* MultiGame::AddFloorToWorld(const Vector3& position, const Vector3& scale, const Vector4& colour, const int collisionResolution) { GameObject* floor = new GameObject(); AABBVolume* volume = new AABBVolume(scale); floor->SetBoundingVolume((CollisionVolume*)volume); floor->GetTransform() .SetScale(scale * 2) .SetPosition(position); floor->SetRenderObject(new RenderObject(&floor->GetTransform(), cubeMesh, basicTex, basicShader)); floor->SetPhysicsObject(new PhysicsObject(&floor->GetTransform(), floor->GetBoundingVolume())); floor->GetPhysicsObject()->SetElasticity(0.0f); floor->GetPhysicsObject()->SetBuoyancy(0.0f); floor->GetPhysicsObject()->SetGravityAffinity(false); floor->GetPhysicsObject()->SetCollisionResolution(collisionResolution); floor->GetPhysicsObject()->SetInverseMass(0); floor->GetPhysicsObject()->InitCubeInertia(); floor->GetRenderObject()->SetColour(colour); world->AddGameObject(floor); return floor; } PlayerObject* MultiGame::AddPlayerToWorld(const Vector3& position) { float radius = 1.0f; float inverseMass = 0.25f; PlayerObject* player = new PlayerObject("Player1"); Vector3 sphereSize = Vector3(radius, radius, radius); SphereVolume* volume = new SphereVolume(radius); player->SetBoundingVolume((CollisionVolume*)volume); player->GetTransform() .SetScale(sphereSize) .SetPosition(position); //player->GetTransform().SetOrientation(Quaternion::EulerAnglesToQuaternion(0,180,0)); player->SetRenderObject(new RenderObject(&player->GetTransform(), charMeshB, basicTex, basicShader)); player->SetPhysicsObject(new PhysicsObject(&player->GetTransform(), player->GetBoundingVolume())); player->GetPhysicsObject()->SetInverseMass(inverseMass); player->GetPhysicsObject()->InitSphereInertia(); player->GetPhysicsObject()->SetBuoyancy(140); player->GetPhysicsObject()->SetElasticity(0.7f); player->GetPhysicsObject()->SetCollisionResolution(CollisionResolution::Impulse | CollisionResolution::Spring | CollisionResolution::Jelly | CollisionResolution::Snow | CollisionResolution::Collect); player->GetRenderObject()->SetColour(Vector4(255, 255, 0, 1)); playerOriginalColour = Vector4(255, 255, 0, 1); world->AddGameObject(player); return player; } GameObject* MultiGame::AddAIOpponentToWorld(const Vector3& position) { //float meshSize = 4.0f; //float inverseMass = 0.5f; float radius = 1.0f; float inverseMass = 0.25f; AIOpponentObject* aiOpponent = new AIOpponentObject("LevelMulti1.txt"); Vector3 sphereSize = Vector3(radius, radius, radius); SphereVolume* volume = new SphereVolume(radius); //keeper->SetOrigin(position); aiOpponent->AddObstacles(obstacles); //AABBVolume* volume = new AABBVolume(Vector3(0.3, 0.9f, 0.3) * meshSize); aiOpponent->SetBoundingVolume((CollisionVolume*)volume); //aiOpponent->GetTransform().SetScale(Vector3(meshSize, meshSize, meshSize)); //aiOpponent->GetTransform().SetPosition(position); aiOpponent->GetTransform() .SetScale(sphereSize) .SetPosition(position); aiOpponent->SetRenderObject(new RenderObject(&aiOpponent->GetTransform(), charMeshA, nullptr, basicShader)); aiOpponent->SetPhysicsObject(new PhysicsObject(&aiOpponent->GetTransform(), aiOpponent->GetBoundingVolume())); aiOpponent->GetPhysicsObject()->SetInverseMass(inverseMass); aiOpponent->GetPhysicsObject()->InitCubeInertia(); aiOpponent->GetPhysicsObject()->SetBuoyancy(70); aiOpponent->GetPhysicsObject()->SetElasticity(0.7f); aiOpponent->GetPhysicsObject()->SetCollisionResolution(CollisionResolution::Impulse | CollisionResolution::Spring | CollisionResolution::Jelly | CollisionResolution::Snow | CollisionResolution::Collect); aiOpponent->SetAIOpponent(aiOpponent); aiOpponent->SetPlayer(playerCharacter); world->AddGameObject(aiOpponent); enemies.push_back(aiOpponent); return aiOpponent; } GameObject* MultiGame::AddCubeToWorld(const Vector3& position, Vector3 dimensions, float inverseMass, const Vector4& colour) { GameObject* cube = new GameObject(); AABBVolume* volume = new AABBVolume(dimensions); cube->SetBoundingVolume((CollisionVolume*)volume); cube->GetTransform() .SetScale(dimensions * 2) .SetPosition(position); cube->SetRenderObject(new RenderObject(&cube->GetTransform(), cubeMesh, basicTex, basicShader)); cube->SetPhysicsObject(new PhysicsObject(&cube->GetTransform(), cube->GetBoundingVolume())); cube->GetPhysicsObject()->SetElasticity((rand() % 100 + 1) / 100.f); cube->GetPhysicsObject()->SetBuoyancy(rand() % 351 + 50); cube->GetPhysicsObject()->SetCollisionResolution(CollisionResolution::Impulse | CollisionResolution::Spring | CollisionResolution::Jelly | CollisionResolution::Snow); cube->GetPhysicsObject()->SetInverseMass(inverseMass); cube->GetPhysicsObject()->InitCubeInertia(); //cube->SetSleep(true); // cube->GetRenderObject()->SetColour(colour); world->AddGameObject(cube); return cube; } GameObject* MultiGame::AddSphereToWorld(const Vector3& position, float radius, float inverseMass, const Vector4& colour) { GameObject* sphere = new GameObject(); Vector3 sphereSize = Vector3(radius, radius, radius); SphereVolume* volume = new SphereVolume(radius); sphere->SetBoundingVolume((CollisionVolume*)volume); sphere->GetTransform() .SetScale(sphereSize) .SetPosition(position); sphere->SetRenderObject(new RenderObject(&sphere->GetTransform(), sphereMesh, basicTex, basicShader)); sphere->SetPhysicsObject(new PhysicsObject(&sphere->GetTransform(), sphere->GetBoundingVolume())); sphere->GetPhysicsObject()->SetElasticity((rand() % 100 + 1) / 100.f); sphere->GetPhysicsObject()->SetBuoyancy(rand() % 351 + 50); //sphere->GetPhysicsObject()->SetElasticity(0.9f); //sphere->GetPhysicsObject()->SetBuoyancy(100.0f); //sphere->GetPhysicsObject()->SetGravityAffinity(false); sphere->GetPhysicsObject()->SetCollisionResolution(CollisionResolution::Impulse | CollisionResolution::Spring | CollisionResolution::Jelly | CollisionResolution::Snow); sphere->GetPhysicsObject()->SetInverseMass(inverseMass); sphere->GetPhysicsObject()->InitSphereInertia(); //sphere->GetPhysicsObject()->SetGravityAffinity(true); //sphere->GetPhysicsObject()->AddForce(Vector3(100,30,35) * forceMagnitude ); sphere->GetPhysicsObject()->AddForce(Vector3(0, 0, 1)); sphere->GetRenderObject()->SetColour(colour); world->AddGameObject(sphere); return sphere; } GameObject* MultiGame::AddWallToWorld(const Vector3& position, const Vector3& scale, const Vector4& colour) { GameObject* wall = new GameObject(); AABBVolume* volume = new AABBVolume(scale); wall->SetBoundingVolume((CollisionVolume*)volume); wall->GetTransform() .SetScale(scale * 2) .SetPosition(position); wall->SetRenderObject(new RenderObject(&wall->GetTransform(), cubeMesh, basicTex, basicShader)); wall->SetPhysicsObject(new PhysicsObject(&wall->GetTransform(), wall->GetBoundingVolume())); wall->GetPhysicsObject()->SetElasticity(0.0f); wall->GetPhysicsObject()->SetBuoyancy(0.0f); wall->GetPhysicsObject()->SetGravityAffinity(false); wall->GetPhysicsObject()->SetCollisionResolution(CollisionResolution::Impulse); wall->GetPhysicsObject()->SetInverseMass(0); wall->GetPhysicsObject()->InitCubeInertia(); wall->GetRenderObject()->SetColour(colour); world->AddGameObject(wall); return wall; } void MultiGame::AddGateToWorld(const Vector3& position, const Vector3& rotation) { GameObject* fencePillar1 = AddRampToWorld(position, Vector3(0.2, 2, 0.3), rotation, 0); GameObject* gate = AddRampToWorld(position + Quaternion::EulerAnglesToQuaternion(rotation.x, rotation.y, rotation.z) * Vector3(12, 0, 0), Vector3(11.5, 1.8, 0.2), rotation, 0.5); GameObject* fencePillar2 = AddRampToWorld(position + Quaternion::EulerAnglesToQuaternion(rotation.x, rotation.y, rotation.z) * Vector3(24, 0, 0), Vector3(0.2, 2, 0.3), rotation, 0); PositionConstraint* constraint = new PositionConstraint(fencePillar1, gate, 12); HingeConstraint* hinge = new HingeConstraint(fencePillar1, gate); FixedHeightConstraint* height = new FixedHeightConstraint(gate, gate->GetTransform().GetPosition().y); fencePillar1->SetSleep(true); gate->SetSleep(true); fencePillar2->SetSleep(true); world->AddConstraint(constraint); world->AddConstraint(hinge); world->AddConstraint(height); } void MultiGame::AddFinishGateToWorld(const Vector3& position, const Vector3& rotation) { GameObject* fencePillar1 = AddRampToWorld(position, Vector3(0.4, 8, 0.6), rotation, 0); GameObject* gate = AddRampToWorld(position + Quaternion::EulerAnglesToQuaternion(rotation.x, rotation.y, rotation.z) * Vector3(12, 2, 0), Vector3(23, 1.8, 0.2), rotation, 0.0); GameObject* fencePillar2 = AddRampToWorld(position + Quaternion::EulerAnglesToQuaternion(rotation.x, rotation.y, rotation.z) * Vector3(24, 0, 0), Vector3(0.4, 8, 0.6), rotation, 0); PositionConstraint* constraint = new PositionConstraint(fencePillar1, gate, 12); HingeConstraint* hinge = new HingeConstraint(fencePillar1, gate); HingeConstraint* hinge2 = new HingeConstraint(fencePillar2, gate); FixedHeightConstraint* height = new FixedHeightConstraint(gate, gate->GetTransform().GetPosition().y); fencePillar1->SetSleep(true); gate->SetSleep(true); fencePillar2->SetSleep(true); world->AddConstraint(constraint); world->AddConstraint(hinge); world->AddConstraint(hinge2); world->AddConstraint(height); } GameObject* MultiGame::AddRampToWorld(const Vector3& position, const Vector3& scale, const Vector3& rotation, const float inverseMass) { GameObject* ramp = new GameObject(); OBBVolume* volume = new OBBVolume(scale); ramp->SetBoundingVolume((CollisionVolume*)volume); ramp->GetTransform() .SetScale(scale * 2) .SetPosition(position); ramp->GetTransform().SetOrientation(Quaternion::EulerAnglesToQuaternion(rotation.x, rotation.y, rotation.z)); ramp->SetRenderObject(new RenderObject(&ramp->GetTransform(), cubeMesh, basicTex, basicShader)); ramp->SetPhysicsObject(new PhysicsObject(&ramp->GetTransform(), ramp->GetBoundingVolume())); ramp->GetPhysicsObject()->SetElasticity(0.0f); ramp->GetPhysicsObject()->SetBuoyancy(0.0f); ramp->GetPhysicsObject()->SetGravityAffinity(false); ramp->GetPhysicsObject()->SetCollisionResolution(CollisionResolution::Impulse); ramp->GetPhysicsObject()->SetInverseMass(inverseMass); ramp->GetPhysicsObject()->InitCubeInertia(); ramp->GetRenderObject()->SetColour(Vector4(1, 1, 1, 1)); world->AddGameObject(ramp); return ramp; } void MultiGame::AddJellyToWorld(const Vector3& position) { AddFloorToWorld(position, Vector3(25, 1.5, 25), Vector4(1, 0, 0, 1), CollisionResolution::Jelly); obstacles.push_back(AddWallToWorld(position + Vector3(27.5, 1, 0), Vector3(4.7, 2.5, 22.5))); //Right obstacles.push_back(AddWallToWorld(position - Vector3(27.5, -1, 0), Vector3(4.7, 2.5, 22.5))); //Left obstacles.push_back(AddWallToWorld(position + Vector3(0, 1, 27.5), Vector3(30, 2.5, 4.7))); //Bottom obstacles.push_back(AddWallToWorld(position - Vector3(0, -1, 27.5), Vector3(30, 2.5, 4.7))); //Up } GameObject* MultiGame::AddBonusToWorld(const Vector3& position, const Vector4& colour) { BonusObject* bonus = new BonusObject(25); SphereVolume* volume = new SphereVolume(0.25f); bonus->SetBoundingVolume((CollisionVolume*)volume); bonus->GetTransform() .SetScale(Vector3(0.25, 0.25, 0.25)) .SetPosition(position); bonus->SetRenderObject(new RenderObject(&bonus->GetTransform(), bonusMesh, nullptr, basicShader)); bonus->SetPhysicsObject(new PhysicsObject(&bonus->GetTransform(), bonus->GetBoundingVolume())); bonus->GetPhysicsObject()->SetInverseMass(1.0f); bonus->GetPhysicsObject()->InitSphereInertia(); bonus->GetRenderObject()->SetColour(colour); world->AddGameObject(bonus); return bonus; } void MultiGame::DrawDisplay(float dt) { renderer->DrawString("Time taken: " + std::to_string(levelTimer), Vector2(5, 10)); renderer->DrawString("Score: " + std::to_string(playerCharacter->GetScore()), Vector2(5, 15)); renderer->DrawString("Points collected: " + std::to_string(playerCharacter->GetPointsCollected()), Vector2(5, 20)); renderer->DrawString("Total items: " + std::to_string(bonus.size()), Vector2(5, 25)); renderer->DrawString("Collected items: " + std::to_string(playerCharacter->GetItems()), Vector2(5, 30)); renderer->DrawString("Remaining items: " + std::to_string(bonus.size() - playerCharacter->GetItems()), Vector2(5, 35)); renderer->DrawString("Enemy score: " + std::to_string(enemies[0]->GetScore()), Vector2(5, 40)); } bool MultiGame::SelectObject() { if (Window::GetKeyboard()->KeyPressed(KeyboardKeys::Q)) { inSelectionMode = !inSelectionMode; if (inSelectionMode) { Window::GetWindow()->ShowOSPointer(true); Window::GetWindow()->LockMouseToWindow(false); } else { Window::GetWindow()->ShowOSPointer(false); Window::GetWindow()->LockMouseToWindow(true); } } if (inSelectionMode) { renderer->DrawString("Press Q to change to camera mode!", Vector2(5, 95)); if (Window::GetMouse()->ButtonDown(NCL::MouseButtons::LEFT)) { if (selectionObject) { //set colour to deselected; selectionObject->GetRenderObject()->SetColour(Vector4(1, 1, 1, 1)); selectionObject = nullptr; lockedObject = nullptr; } Ray ray = CollisionDetection::BuildRayFromMouse(*world->GetMainCamera()); RayCollision closestCollision; if (world->Raycast(ray, closestCollision, true)) { selectionObject = (GameObject*)closestCollision.node; selectionObject->GetRenderObject()->SetColour(Vector4(0, 1, 0, 1)); renderer->DrawString("Pos x: " + std::to_string(selectionObject->GetRenderObject()->GetTransform()->GetPosition().x), Vector2(55, 5)); renderer->DrawString("Pos y: " + std::to_string(selectionObject->GetRenderObject()->GetTransform()->GetPosition().y), Vector2(55, 10)); renderer->DrawString("Pos z: " + std::to_string(selectionObject->GetRenderObject()->GetTransform()->GetPosition().z), Vector2(55, 15)); renderer->DrawString("Object name: " + selectionObject->GetName(), Vector2(55, 20)); return true; } else { return false; } } } else { renderer->DrawString("Press Q to change to select mode!", Vector2(5, 95)); } return false; }