void World::update() { uint32_t updateTime = SDL_GetTicks(); float dtime = (updateTime-lastUpdateTime)/1000.f; // If F5 released, reload the scene if (wasF5Down and not Input::isKeyDown(SDL_SCANCODE_F5)) { if (Input::isKeyDown(SDL_SCANCODE_LSHIFT) || Input::isKeyDown(SDL_SCANCODE_RSHIFT)) { // Enable reload-on-change (inotify on Linux) } loadScene(currentScenePath); } wasF5Down = Input::isKeyDown(SDL_SCANCODE_F5); // If Tab released, toggle editor if (wasTabDown and not Input::isKeyDown(SDL_SCANCODE_TAB)) { isEditorShown = !isEditorShown; } wasTabDown = Input::isKeyDown(SDL_SCANCODE_F5); Entity &player = scene->player; Health &plrHealth = player.getComponent<Health>(); Transform &plrTform = player.getComponent<Transform>(); PlayerMotion &plrMotion = player.getComponent<PlayerMotion>(); // Check if player is still alive if (not plrHealth.isAlive()) { plrTform.position = scene->start.getComponent<Transform>().position; plrHealth.revive(); hidePortals(); } // Calculate the view and new velocity of the player // FIXME: don't do this here, let a manager handle plrMotion.mouseLook(); plrMotion.move(dtime); // Figure out the provisional new player position Vector3f pos = plrTform.position + plrMotion.velocity; //Y collision BoxCollider bboxY(Vector3f(plrTform.position.x, pos.y, plrTform.position.z), plrTform.scale); if (collidesWithWalls(bboxY)) { bool portaling = false; portaling = WorldHelper::isPlayerPortalingY(bboxY, &player, scene); if (not portaling and not plrMotion.noclip) { if (plrMotion.velocity.y < 0) { if(plrMotion.velocity.y < -HURT_VELOCITY) { std::uniform_int_distribution<> dis(0, PLAYER_FALL_SOUND.size()-1); player.getComponent<SoundSource>().playSound( Environment::getDataDir() + PLAYER_FALL_SOUND[dis(generator)]); } plrMotion.grounded = true; } plrMotion.velocity.y = 0; } } else { plrMotion.grounded = false; } //X collision BoxCollider bboxX(Vector3f(pos.x, plrTform.position.y, plrTform.position.z), plrTform.scale); if (collidesWithWalls(bboxX)) { bool portaling = false; portaling = WorldHelper::isPlayerPortalingX(bboxX, &player, scene); if (not portaling and not plrMotion.noclip) { plrMotion.velocity.x = 0; } } //Z collision BoxCollider bboxZ(Vector3f(plrTform.position.x, plrTform.position.y, pos.z), plrTform.scale); if (collidesWithWalls(bboxZ)) { bool portaling = false; portaling = WorldHelper::isPlayerPortalingZ(bboxZ, &player, scene); if (not portaling and not plrMotion.noclip) { plrMotion.velocity.z = 0; } } for (Entity &e : scene->entities) { // Trigger if (e.hasComponent<Trigger>()) { const Trigger &trigger = e.getComponent<Trigger>(); const Transform &trTform = e.getComponent<Transform>(); BoxCollider playerCollider(plrTform.position, plrTform.scale); BoxCollider triggerCollider(trTform.position, trTform.scale); if (playerCollider.collidesWith(triggerCollider)) { if (trigger.type == "radiation") { player.getComponent<Health>().harm(.1f); } else if (trigger.type == "death") { player.getComponent<Health>().kill(); printf("Death touched\n"); } else if (trigger.type == "win") { if(currentLevel + 1 < mapList.size()) { currentLevel++; } loadScene(mapList[currentLevel]); printf("Win touched\n"); } else if (trigger.type == "map") { printf("Map Trigger touched\n"); throw __FILE__ ": Map trigger type de-implemented, please reimplement"; //loadScene(trigger.reference); } else if (trigger.type == "button") { printf("Button touched\n"); } else { printf("Some trigger touched: %s\n", trigger.type.c_str()); } } } } pos = plrTform.position + plrMotion.velocity; // Check if the player is moving through a portal BoxCollider playerCollider(pos, plrTform.scale); for (EntityPair &p : scene->portalPairs) { Portal &portal1 = p.first->getComponent<Portal>(), &portal2 = p.second->getComponent<Portal>(); Transform &p1Tform = p.first->getComponent<Transform>(), &p2Tform = p.second->getComponent<Transform>(); if (portal1.open and portal2.open) { if (portal1.throughPortal(playerCollider)) { plrTform.position = p2Tform.position; float rotation = p2Tform.rotation.y - p1Tform.rotation.y + rad(180); plrTform.rotation.y += rotation; // Transform the velocity of the player float velocity = plrMotion.velocity.length(); plrMotion.velocity = portal2.getDirection() * velocity; } if (portal2.throughPortal(playerCollider)) { plrTform.position = p1Tform.position; float rotation = p1Tform.rotation.y - p2Tform.rotation.y + rad(180); plrTform.rotation.y += rotation; // Transform the velocity of the player float velocity = plrMotion.velocity.length(); plrMotion.velocity = portal1.getDirection() * velocity; } } } //Add velocity to the player position plrTform.position += plrMotion.velocity; //Parent camera to player scene->camera.setPerspective(); int vpWidth, vpHeight; renderer->getViewport()->getSize(&vpWidth, &vpHeight); scene->camera.setAspect((float)vpWidth / vpHeight); scene->camera.setPosition(plrTform.position + Vector3f(0, plrTform.scale.y/2, 0)); scene->camera.setRotation(plrTform.rotation); //Check if the end of the level has been reached float distToEnd = (scene->end.getComponent<Transform>().position - plrTform.position).length(); if (distToEnd < 1) { if(currentLevel + 1 < mapList.size()) { currentLevel++; } loadScene(mapList[currentLevel]); } lastUpdateTime = updateTime; }
void World::update() { Player* player = &scene->player; player->mouseLook(); player->move(); Vector3f pos = add(player->position, player->velocity); //FIXME Remake the collision system to be less faulty and ugly //Y collision BoxCollider bboxY(Vector3f(player->position.x, pos.y, player->position.z), player->scale); if (collidesWithWalls(bboxY)) { bool portaling = false; if (scene->bluePortal.open && scene->orangePortal.open) { if(scene->bluePortal.inPortal(bboxY)) { if(scene->bluePortal.rotation.x == -90 || scene->bluePortal.rotation.x == 90) { portaling = true; } } if(scene->orangePortal.inPortal(bboxY)) { if(scene->orangePortal.rotation.x == -90 || scene->orangePortal.rotation.x == 90) { portaling = true; } } } if(!portaling) { if (player->velocity.y < 0) { if(player->velocity.y < -0.18f) { std::uniform_int_distribution<> dis(0, PLAYER_FALL_SOUND.size()-1); SoundManager::PlaySound(Environment::getDataDir() + PLAYER_FALL_SOUND[dis(generator)],player,SoundManager::PRIMARY); } player->grounded = true; } player->velocity.y = 0; } } //X collision BoxCollider bboxX(Vector3f(pos.x, player->position.y, player->position.z), player->scale); if (collidesWithWalls(bboxX)) { bool portaling = false; if (scene->bluePortal.open && scene->orangePortal.open) { if(scene->bluePortal.inPortal(bboxX)) { if(scene->bluePortal.rotation.x == 0 && (scene->bluePortal.rotation.y == -90 || scene->bluePortal.rotation.y == 90)) { portaling = true; } } if(scene->orangePortal.inPortal(bboxX)) { if(scene->bluePortal.rotation.x == 0 && (scene->orangePortal.rotation.y == -90 || scene->orangePortal.rotation.y == 90)) { portaling = true; } } } if(!portaling) { player->velocity.x = 0; } } //Z collision BoxCollider bboxZ(Vector3f(player->position.x, player->position.y, pos.z), player->scale); if (collidesWithWalls(bboxZ)) { bool portaling = false; if (scene->bluePortal.open && scene->orangePortal.open) { if(scene->bluePortal.inPortal(bboxZ)) { if(scene->bluePortal.rotation.x == 0 && (scene->bluePortal.rotation.y == 0 || scene->bluePortal.rotation.y == 180)) { portaling = true; } } if(scene->orangePortal.inPortal(bboxZ)) { if(scene->orangePortal.rotation.x == 0 && (scene->orangePortal.rotation.y == 0 || scene->orangePortal.rotation.y == 180)) { portaling = true; } } } if(!portaling) { player->velocity.z = 0; } } //Trigger for (unsigned int i = 0; i < scene->triggers.size(); i++) { Trigger trigger = scene->triggers[i]; BoxCollider playerCollider(player->position, player->scale); BoxCollider triggerCollider(trigger.position, trigger.scale); if (playerCollider.collidesWith(triggerCollider)) { if (trigger.type == "radiation") { player->harm(10); } else if (trigger.type == "death") { player->kill(); printf("Death touched\n"); } else if (trigger.type == "win") { printf("Win touched\n"); } else { printf("Some trigger touched: %s\n", trigger.type.c_str()); } } } pos = player->position + player->velocity; //Check if the player is moving through a portal BoxCollider playerCollider(pos, player->scale); if (scene->bluePortal.open && scene->orangePortal.open) { if (scene->bluePortal.throughPortal(playerCollider)) { player->position.set(scene->orangePortal.position); float rotation = scene->orangePortal.rotation.y - scene->bluePortal.rotation.y + 180; player->rotation.y += rotation; //Transform the velocity of the player float velocity = player->velocity.length(); player->velocity = *scene->orangePortal.getDirection().scale(velocity); } if (scene->orangePortal.throughPortal(playerCollider)) { player->position.set(scene->bluePortal.position); float rotation = scene->bluePortal.rotation.y - scene->orangePortal.rotation.y + 180; player->rotation.y += rotation; //Transform the velocity of the player float velocity = player->velocity.length(); player->velocity = *scene->bluePortal.getDirection().scale(velocity); } } //Add velocity to the player position player->position.add(player->velocity); //Parent camera to player scene->camera.position.set(scene->player.position); scene->camera.position.y += scene->player.scale.y/2; scene->camera.rotation.set(scene->player.rotation); //Check if the end of the level has been reached float distToEnd = (scene->end.position - scene->player.position).length(); if (distToEnd < 1) { if(currentLevel + 1 < mapList.size()) { currentLevel++; } loadScene(mapList[currentLevel]); } }