Browse Source

Clean up main loop and application states

master
C. J. Howard 6 years ago
parent
commit
c171372601
12 changed files with 1142 additions and 1068 deletions
  1. +4
    -2
      CMakeLists.txt
  2. +1
    -1
      data
  3. +720
    -68
      src/application.cpp
  4. +80
    -64
      src/application.hpp
  5. +123
    -0
      src/states/loading-state.cpp
  6. +39
    -0
      src/states/loading-state.hpp
  7. +92
    -0
      src/states/main-menu-state.cpp
  8. +43
    -0
      src/states/main-menu-state.hpp
  9. +12
    -652
      src/states/splash-state.cpp
  10. +1
    -10
      src/states/splash-state.hpp
  11. +26
    -264
      src/states/title-state.cpp
  12. +1
    -7
      src/states/title-state.hpp

+ 4
- 2
CMakeLists.txt View File

@ -98,12 +98,14 @@ set(EXECUTABLE_SOURCES
${EXECUTABLE_SOURCE_DIR}/application-state.cpp
${EXECUTABLE_SOURCE_DIR}/application.hpp
${EXECUTABLE_SOURCE_DIR}/application.cpp
${EXECUTABLE_SOURCE_DIR}/states/loading-state.hpp
${EXECUTABLE_SOURCE_DIR}/states/loading-state.cpp
${EXECUTABLE_SOURCE_DIR}/states/splash-state.hpp
${EXECUTABLE_SOURCE_DIR}/states/splash-state.cpp
${EXECUTABLE_SOURCE_DIR}/states/title-state.hpp
${EXECUTABLE_SOURCE_DIR}/states/title-state.cpp
${EXECUTABLE_SOURCE_DIR}/states/experiment-state.hpp
${EXECUTABLE_SOURCE_DIR}/states/experiment-state.cpp
${EXECUTABLE_SOURCE_DIR}/states/main-menu-state.hpp
${EXECUTABLE_SOURCE_DIR}/states/main-menu-state.cpp
${EXECUTABLE_SOURCE_DIR}/ui/ui.hpp
${EXECUTABLE_SOURCE_DIR}/ui/ui.cpp
${EXECUTABLE_SOURCE_DIR}/ui/tween.hpp

+ 1
- 1
data

@ -1 +1 @@
Subproject commit 20ee9d1816867003a3246bc8ce60c60df2c2c7b7
Subproject commit 5c2d9e19f18fd4085ee0aa4096aa4d63e9e3edef

+ 720
- 68
src/application.cpp View File

@ -21,11 +21,15 @@
#include "application-state.hpp"
#include "model-loader.hpp"
#include "material-loader.hpp"
#include "states/loading-state.hpp"
#include "states/splash-state.hpp"
#include "states/title-state.hpp"
#include "states/experiment-state.hpp"
#include "states/main-menu-state.hpp"
#include "debug.hpp"
#include "camera-controller.hpp"
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <SDL.h>
#define OPENGL_VERSION_MAJOR 3
@ -307,73 +311,11 @@ Application::Application(int argc, char* argv[]):
keyboard = (*inputManager->getKeyboards()).front();
mouse = (*inputManager->getMice()).front();
// Setup menu navigation controls
menuControlProfile = new ControlProfile(inputManager);
menuControlProfile->registerControl("menu_left", &menuLeft);
menuControlProfile->registerControl("menu_right", &menuRight);
menuControlProfile->registerControl("menu_up", &menuUp);
menuControlProfile->registerControl("menu_down", &menuDown);
menuControlProfile->registerControl("menu_select", &menuSelect);
menuControlProfile->registerControl("menu_cancel", &menuCancel);
menuControlProfile->registerControl("toggle_fullscreen", &toggleFullscreen);
menuControlProfile->registerControl("escape", &escape);
menuLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
//menuLeft.bindKey(keyboard, SDL_SCANCODE_A);
menuRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
//menuRight.bindKey(keyboard, SDL_SCANCODE_D);
menuUp.bindKey(keyboard, SDL_SCANCODE_UP);
//menuUp.bindKey(keyboard, SDL_SCANCODE_W);
menuDown.bindKey(keyboard, SDL_SCANCODE_DOWN);
//menuDown.bindKey(keyboard, SDL_SCANCODE_S);
menuSelect.bindKey(keyboard, SDL_SCANCODE_RETURN);
menuSelect.bindKey(keyboard, SDL_SCANCODE_SPACE);
menuSelect.bindKey(keyboard, SDL_SCANCODE_Z);
menuCancel.bindKey(keyboard, SDL_SCANCODE_BACKSPACE);
menuCancel.bindKey(keyboard, SDL_SCANCODE_X);
toggleFullscreen.bindKey(keyboard, SDL_SCANCODE_F11);
escape.bindKey(keyboard, SDL_SCANCODE_ESCAPE);
// Setup in-game controls
gameControlProfile = new ControlProfile(inputManager);
gameControlProfile->registerControl("camera-move-forward", &cameraMoveForward);
gameControlProfile->registerControl("camera-move-back", &cameraMoveBack);
gameControlProfile->registerControl("camera-move-left", &cameraMoveLeft);
gameControlProfile->registerControl("camera-move-right", &cameraMoveRight);
gameControlProfile->registerControl("camera-rotate-cw", &cameraRotateCW);
gameControlProfile->registerControl("camera-rotate-ccw", &cameraRotateCCW);
gameControlProfile->registerControl("camera-zoom-in", &cameraZoomIn);
gameControlProfile->registerControl("camera-zoom-out", &cameraZoomOut);
gameControlProfile->registerControl("camera-toggle-nest-view", &cameraToggleNestView);
gameControlProfile->registerControl("camera-toggle-overhead-view", &cameraToggleOverheadView);
gameControlProfile->registerControl("walk-forward", &walkForward);
gameControlProfile->registerControl("walk-back", &walkBack);
gameControlProfile->registerControl("turn-left", &turnLeft);
gameControlProfile->registerControl("turn-right", &turnRight);
cameraMoveForward.bindKey(keyboard, SDL_SCANCODE_W);
cameraMoveBack.bindKey(keyboard, SDL_SCANCODE_S);
cameraMoveLeft.bindKey(keyboard, SDL_SCANCODE_A);
cameraMoveRight.bindKey(keyboard, SDL_SCANCODE_D);
cameraRotateCW.bindKey(keyboard, SDL_SCANCODE_Q);
cameraRotateCCW.bindKey(keyboard, SDL_SCANCODE_E);
cameraZoomIn.bindKey(keyboard, SDL_SCANCODE_EQUALS);
cameraZoomOut.bindKey(keyboard, SDL_SCANCODE_MINUS);
cameraZoomIn.bindMouseWheelAxis(mouse, MouseWheelAxis::POSITIVE_Y);
cameraZoomOut.bindMouseWheelAxis(mouse, MouseWheelAxis::NEGATIVE_Y);
cameraToggleOverheadView.bindKey(keyboard, SDL_SCANCODE_R);
cameraToggleNestView.bindKey(keyboard, SDL_SCANCODE_F);
walkForward.bindKey(keyboard, SDL_SCANCODE_UP);
walkBack.bindKey(keyboard, SDL_SCANCODE_DOWN);
turnLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
turnRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
cameraOverheadView = true;
cameraNestView = false;
// Allocate states
loadingState = new LoadingState(this);
splashState = new SplashState(this);
titleState = new TitleState(this);
experimentState = new ExperimentState(this);
mainMenuState = new MainMenuState(this);
// Setup loaders
textureLoader = new TextureLoader();
@ -381,8 +323,12 @@ Application::Application(int argc, char* argv[]):
modelLoader = new ModelLoader();
modelLoader->setMaterialLoader(materialLoader);
// Enter splash state
state = nextState = splashState;
// Allocate game variables
surfaceCam = new SurfaceCameraController();
tunnelCam = new TunnelCameraController();
// Enter loading state
state = nextState = loadingState;
state->enter();
}
@ -395,20 +341,73 @@ Application::~Application()
int Application::execute()
{
// Start frame timer
frameTimer.start();
while (state != nullptr)
{
state->execute();
// Calculate delta time (in seconds) then reset frame timer
dt = static_cast<float>(frameTimer.microseconds().count()) / 1000000.0f;
frameTimer.reset();
// If the user tried to close the application
if (inputManager->wasClosed() || escape.isTriggered())
{
// Close the application
close(EXIT_SUCCESS);
}
else
{
// Execute current state
state->execute();
}
// Check for state change
if (nextState != state)
{
// Exit current state
state->exit();
// Enter next state (if valid)
state = nextState;
if (nextState != nullptr)
{
state->enter();
// Reset frame timer to counteract frames eaten by state exit() and enter() functions
frameTimer.reset();
}
}
// Update controls
menuControlProfile->update();
gameControlProfile->update();
// Update input
inputManager->update();
// Check if fullscreen was toggled
if (toggleFullscreen.isTriggered() && !toggleFullscreen.wasTriggered())
{
changeFullscreen();
}
// Perform tweening
tweener->update(dt);
// Update UI
uiRootElement->update();
uiBatcher->batch(uiBatch, uiRootElement);
// Clear depth and stencil buffers
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Render scene
renderer.render(scene);
// Swap buffers
SDL_GL_SwapWindow(window);
}
return terminationCode;
@ -525,6 +524,636 @@ void Application::saveUserSettings()
}
}
bool Application::loadModels()
{
antModel = modelLoader->load("data/models/debug-worker.mdl");
antHillModel = modelLoader->load("data/models/ant-hill.mdl");
if (!antModel || !antHillModel)
{
return false;
}
antModelInstance.setModel(antModel);
antModelInstance.setTransform(Transform::getIdentity());
antHillModelInstance.setModel(antHillModel);
antHillModelInstance.setRotation(glm::angleAxis(glm::radians(90.0f), Vector3(1, 0, 0)));
return true;
}
bool Application::loadScene()
{
// Create scene layers
backgroundLayer = scene.addLayer();
defaultLayer = scene.addLayer();
uiLayer = scene.addLayer();
// Debug
lineBatcher = new LineBatcher(4096);
BillboardBatch* lineBatch = lineBatcher->getBatch();
lineBatch->setAlignment(&camera, BillboardAlignmentMode::CYLINDRICAL);
lineBatch->setAlignmentVector(Vector3(1, 0, 0));
defaultLayer->addObject(lineBatch);
return true;
}
bool Application::loadUI()
{
// Load menu font
menuFont = new Font(512, 512);
FontLoader* fontLoader = new FontLoader();
if (!fontLoader->load("data/fonts/Varela-Regular.ttf", fontSizePX, menuFont))
{
std::cerr << "Failed to load font" << std::endl;
}
delete fontLoader;
// Load UI textures
textureLoader->setGamma(1.0f);
textureLoader->setCubemap(false);
textureLoader->setMipmapChain(false);
textureLoader->setMaxAnisotropy(1.0f);
splashTexture = textureLoader->load("data/textures/splash.png");
titleTexture = textureLoader->load("data/textures/title.png");
levelActiveTexture = textureLoader->load("data/textures/ui-level-active.png");
levelInactiveTexture = textureLoader->load("data/textures/ui-level-inactive.png");
levelConnectorTexture = textureLoader->load("data/textures/ui-level-connector.png");
// Get strings
std::string pressAnyKeyString;
std::string backString;
std::string challengeString;
std::string experimentString;
std::string settingsString;
std::string quitString;
std::string loadString;
std::string newString;
std::string videoString;
std::string audioString;
std::string controlsString;
std::string gameString;
std::string resumeString;
std::string returnToMainMenuString;
std::string quitToDesktopString;
strings.get("press-any-key", &pressAnyKeyString);
strings.get("back", &backString);
strings.get("challenge", &challengeString);
strings.get("experiment", &experimentString);
strings.get("settings", &settingsString);
strings.get("quit", &quitString);
strings.get("load", &loadString);
strings.get("new", &newString);
strings.get("video", &videoString);
strings.get("audio", &audioString);
strings.get("controls", &controlsString);
strings.get("game", &gameString);
strings.get("resume", &resumeString);
strings.get("return-to-main-menu", &returnToMainMenuString);
strings.get("quit-to-desktop", &quitToDesktopString);
// Set colors
selectedColor = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
deselectedColor = Vector4(0.0f, 0.0f, 0.0f, 0.35f);
// Setup root UI element
uiRootElement = new UIContainer();
uiRootElement->setDimensions(Vector2(width, height));
mouse->addMouseMotionObserver(uiRootElement);
mouse->addMouseButtonObserver(uiRootElement);
// Create blackout element (for screen transitions)
blackoutImage = new UIImage();
blackoutImage->setDimensions(Vector2(width, height));
blackoutImage->setLayerOffset(99);
blackoutImage->setTintColor(Vector4(0.0f, 0.0f, 0.0f, 1.0f));
blackoutImage->setVisible(false);
uiRootElement->addChild(blackoutImage);
// Create splash screen element
splashImage = new UIImage();
splashImage->setAnchor(Anchor::CENTER);
splashImage->setDimensions(Vector2(splashTexture->getWidth(), splashTexture->getHeight()));
splashImage->setTexture(splashTexture);
splashImage->setVisible(false);
uiRootElement->addChild(splashImage);
// Create game title element
titleImage = new UIImage();
titleImage->setAnchor(Vector2(0.5f, 0.0f));
titleImage->setDimensions(Vector2(titleTexture->getWidth(), titleTexture->getHeight()));
titleImage->setTranslation(Vector2(0.0f, (int)(height * (1.0f / 3.0f) - titleTexture->getHeight())));
titleImage->setTexture(titleTexture);
titleImage->setVisible(false);
uiRootElement->addChild(titleImage);
/*
copyrightImage = new UIImage();
copyrightImage->setAnchor(Vector2(0.5f, 1.0f));
copyrightImage->setDimensions(Vector2(copyrightTextureWidth, copyrightTextureHeight));
copyrightImage->setTranslation(Vector2(-.5f, (int)(-height * (1.0f / 10.0f) - copyrightTextureHeight * 0.5f)));
copyrightImage->setTexture(nullptr);
copyrightImage->setVisible(false);
uiRootElement->addChild(copyrightImage);
*/
// Create "Press any key" element
anyKeyLabel = new UILabel();
anyKeyLabel->setAnchor(Vector2(0.5f, 1.0f));
anyKeyLabel->setFont(menuFont);
anyKeyLabel->setTranslation(Vector2(0.0f, (int)(-height * (1.0f / 3.0f)/* - menuFont->getMetrics().getHeight() * 0.5f*/)));
anyKeyLabel->setText(pressAnyKeyString);
anyKeyLabel->setVisible(false);
uiRootElement->addChild(anyKeyLabel);
// Create main menu selector element
menuSelectorLabel = new UILabel();
menuSelectorLabel->setAnchor(Anchor::TOP_LEFT);
menuSelectorLabel->setFont(menuFont);
menuSelectorLabel->setText("<");
menuSelectorLabel->setTintColor(selectedColor);
menuSelectorLabel->setVisible(false);
uiRootElement->addChild(menuSelectorLabel);
// Create main menu elements
mainMenuContainer = new UIContainer();
mainMenuContainer->setDimensions(Vector2(width, menuFont->getMetrics().getHeight() * 4));
mainMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
mainMenuContainer->setVisible(false);
mainMenuContainer->setActive(false);
uiRootElement->addChild(mainMenuContainer);
challengeLabel = new UILabel();
challengeLabel->setFont(menuFont);
challengeLabel->setText(challengeString);
challengeLabel->setTintColor(deselectedColor);
experimentLabel = new UILabel();
experimentLabel->setFont(menuFont);
experimentLabel->setText(experimentString);
experimentLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight()));
experimentLabel->setTintColor(deselectedColor);
settingsLabel = new UILabel();
settingsLabel->setFont(menuFont);
settingsLabel->setText(settingsString);
settingsLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 2));
settingsLabel->setTintColor(deselectedColor);
quitLabel = new UILabel();
quitLabel->setFont(menuFont);
quitLabel->setText(quitString);
quitLabel->setTintColor(deselectedColor);
quitLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 3));
mainMenuContainer->addChild(challengeLabel);
mainMenuContainer->addChild(experimentLabel);
mainMenuContainer->addChild(settingsLabel);
mainMenuContainer->addChild(quitLabel);
// Create challenge menu elements
challengeMenuContainer = new UIContainer();
challengeMenuContainer->setDimensions(Vector2(width, menuFont->getMetrics().getHeight() * 4));
challengeMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
challengeMenuContainer->setVisible(false);
challengeMenuContainer->setActive(false);
uiRootElement->addChild(challengeMenuContainer);
// Create experiment menu elements
experimentMenuContainer = new UIContainer();
experimentMenuContainer->setDimensions(Vector2(width, menuFont->getMetrics().getHeight() * 3));
experimentMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
experimentMenuContainer->setVisible(false);
experimentMenuContainer->setActive(false);
uiRootElement->addChild(experimentMenuContainer);
loadLabel = new UILabel();
loadLabel->setFont(menuFont);
loadLabel->setText(loadString);
loadLabel->setTintColor(deselectedColor);
loadLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 0));
experimentMenuContainer->addChild(loadLabel);
newLabel = new UILabel();
newLabel->setFont(menuFont);
newLabel->setText(newString);
newLabel->setTintColor(deselectedColor);
newLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 1));
experimentMenuContainer->addChild(newLabel);
experimentBackLabel = new UILabel();
experimentBackLabel->setFont(menuFont);
experimentBackLabel->setText(backString);
experimentBackLabel->setTintColor(deselectedColor);
experimentBackLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 2));
experimentMenuContainer->addChild(experimentBackLabel);
// Create settings menu elements
settingsMenuContainer = new UIContainer();
settingsMenuContainer->setDimensions(Vector2(width, menuFont->getMetrics().getHeight() * 5));
settingsMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
settingsMenuContainer->setVisible(false);
settingsMenuContainer->setActive(false);
uiRootElement->addChild(settingsMenuContainer);
videoLabel = new UILabel();
videoLabel->setFont(menuFont);
videoLabel->setText(videoString);
videoLabel->setTintColor(deselectedColor);
videoLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 0));
settingsMenuContainer->addChild(videoLabel);
audioLabel = new UILabel();
audioLabel->setFont(menuFont);
audioLabel->setText(audioString);
audioLabel->setTintColor(deselectedColor);
audioLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 1));
settingsMenuContainer->addChild(audioLabel);
controlsLabel = new UILabel();
controlsLabel->setFont(menuFont);
controlsLabel->setText(controlsString);
controlsLabel->setTintColor(deselectedColor);
controlsLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 2));
settingsMenuContainer->addChild(controlsLabel);
gameLabel = new UILabel();
gameLabel->setFont(menuFont);
gameLabel->setText(gameString);
gameLabel->setTintColor(deselectedColor);
gameLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 3));
settingsMenuContainer->addChild(gameLabel);
settingsBackLabel = new UILabel();
settingsBackLabel->setFont(menuFont);
settingsBackLabel->setText(backString);
settingsBackLabel->setTintColor(deselectedColor);
settingsBackLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 4));
settingsMenuContainer->addChild(settingsBackLabel);
// Create pause menu elements
pauseMenuContainer = new UIContainer();
pauseMenuContainer->setDimensions(Vector2(width, menuFont->getMetrics().getHeight() * 6));
pauseMenuContainer->setAnchor(Anchor::CENTER);
pauseMenuContainer->setVisible(false);
pauseMenuContainer->setActive(false);
uiRootElement->addChild(pauseMenuContainer);
pausedResumeLabel = new UILabel();
pausedResumeLabel->setFont(menuFont);
pausedResumeLabel->setText(resumeString);
pausedResumeLabel->setTintColor(deselectedColor);
pausedResumeLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 0));
pauseMenuContainer->addChild(pausedResumeLabel);
returnToMainMenuLabel = new UILabel();
returnToMainMenuLabel->setFont(menuFont);
returnToMainMenuLabel->setText(returnToMainMenuString);
returnToMainMenuLabel->setTintColor(deselectedColor);
returnToMainMenuLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 1));
pauseMenuContainer->addChild(returnToMainMenuLabel);
quitToDesktopLabel = new UILabel();
quitToDesktopLabel->setFont(menuFont);
quitToDesktopLabel->setText(quitToDesktopString);
quitToDesktopLabel->setTintColor(deselectedColor);
quitToDesktopLabel->setTranslation(Vector2(0.0f, menuFont->getMetrics().getHeight() * 2));
pauseMenuContainer->addChild(quitToDesktopLabel);
// Create level selector elements
levelSelectorContainer = new UIContainer();
levelSelectorContainer->setDimensions(Vector2(levelActiveTexture->getWidth() * 10 + 48 * 9, levelActiveTexture->getHeight()));
levelSelectorContainer->setAnchor(Vector2(0.5f, 1.0f));
levelSelectorContainer->setTranslation(Vector2(0.0f, -levelActiveTexture->getHeight()));
levelSelectorContainer->setVisible(false);
levelSelectorContainer->setActive(false);
uiRootElement->addChild(levelSelectorContainer);
for (int i = 0; i < 10; ++i)
{
levelSelections[i] = new UIImage();
levelSelections[i]->setAnchor(Vector2(0.0f, 0.5f));
levelSelections[i]->setDimensions(Vector2(levelActiveTexture->getWidth(), levelActiveTexture->getHeight()));
levelSelections[i]->setTranslation(Vector2(i * 96.0f, 0.0f));
levelSelections[i]->setTexture(levelInactiveTexture);
levelSelections[i]->setVisible(true);
levelSelectorContainer->addChild(levelSelections[i]);
if (i < 9)
{
levelConnectors[i] = new UIImage();
levelConnectors[i]->setAnchor(Vector2(0.0f, 0.5f));
levelConnectors[i]->setDimensions(Vector2(levelConnectorTexture->getWidth(), levelConnectorTexture->getHeight()));
levelConnectors[i]->setTranslation(Vector2((i + 1) * 96.0f - 50.0f, 0.0f));
levelConnectors[i]->setTexture(levelConnectorTexture);
levelConnectors[i]->setVisible(true);
levelSelectorContainer->addChild(levelConnectors[i]);
}
}
// Create tweener
tweener = new Tweener();
// Setup screen fade in/fade out tween
fadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
fadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, blackoutImage, std::placeholders::_1));
tweener->addTween(fadeInTween);
fadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
fadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, blackoutImage, std::placeholders::_1));
tweener->addTween(fadeOutTween);
// Setup splash screen tween
splashFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
splashFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, splashImage, std::placeholders::_1));
tweener->addTween(splashFadeInTween);
splashHangTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, 1.0f, 0.0f, 1.0f);
tweener->addTween(splashHangTween);
splashFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
splashFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, splashImage, std::placeholders::_1));
tweener->addTween(splashFadeOutTween);
splashFadeInTween->setEndCallback(std::bind(TweenBase::start, splashHangTween));
splashHangTween->setEndCallback(std::bind(TweenBase::start, splashFadeOutTween));
splashFadeOutTween->setEndCallback(std::bind(Application::changeState, this, titleState));
// Setup game title tween
titleFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 2.0f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
titleFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, titleImage, std::placeholders::_1));
tweener->addTween(titleFadeInTween);
titleFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.25f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
titleFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, titleImage, std::placeholders::_1));
tweener->addTween(titleFadeOutTween);
// Setup copyright tween
copyrightFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 1.0f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
copyrightFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, copyrightImage, std::placeholders::_1));
tweener->addTween(copyrightFadeInTween);
copyrightFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.25f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
copyrightFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, copyrightImage, std::placeholders::_1));
tweener->addTween(copyrightFadeOutTween);
// Setup "Press any key" tween
anyKeyFadeInTween = new Tween<Vector4>(EaseFunction::LINEAR, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
anyKeyFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, anyKeyLabel, std::placeholders::_1));
tweener->addTween(anyKeyFadeInTween);
anyKeyFadeOutTween = new Tween<Vector4>(EaseFunction::LINEAR, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
anyKeyFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, anyKeyLabel, std::placeholders::_1));
anyKeyFadeInTween->setEndCallback(std::bind(TweenBase::start, anyKeyFadeOutTween));
anyKeyFadeOutTween->setEndCallback(std::bind(TweenBase::start, anyKeyFadeInTween));
tweener->addTween(anyKeyFadeOutTween);
float menuFadeInDuration = 0.15f;
Vector4 menuFadeInStartColor = Vector4(1.0f, 1.0f, 1.0f, 0.0f);
Vector4 menuFadeInDeltaColor = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
float menuFadeOutDuration = 0.15f;
Vector4 menuFadeOutStartColor = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 menuFadeOutDeltaColor = Vector4(0.0f, 0.0f, 0.0f, -1.0f);
float menuSlideInDuration = 0.35f;
Vector2 menuSlideInStartTranslation = Vector2(-64.0f, 0.0f);
Vector2 menuSlideInDeltaTranslation = Vector2(128.0f, 0.0f);
float levelSelectorSlideInDuration = 0.35f;
Vector2 levelSelectorSlideInStartTranslation = Vector2(0.0f, levelActiveTexture->getHeight());
Vector2 levelSelectorSlideInDeltaTranslation = Vector2(0.0f, -levelActiveTexture->getHeight() * 2.0f);
// Setup main menu tween
menuFadeInTween = new Tween<Vector4>(EaseFunction::OUT_QUINT, 0.0f, menuFadeInDuration, menuFadeInStartColor, menuFadeInDeltaColor);
tweener->addTween(menuFadeInTween);
menuFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_QUINT, 0.0f, menuFadeOutDuration, menuFadeOutStartColor, menuFadeOutDeltaColor);
tweener->addTween(menuFadeOutTween);
menuSlideInTween = new Tween<Vector2>(EaseFunction::OUT_QUINT, 0.0f, menuSlideInDuration, menuSlideInStartTranslation, menuSlideInDeltaTranslation);
tweener->addTween(menuSlideInTween);
// Setup level selector tween
levelSelectorSlideInTween = new Tween<Vector2>(EaseFunction::OUT_QUINT, 0.0f, levelSelectorSlideInDuration, levelSelectorSlideInStartTranslation, levelSelectorSlideInDeltaTranslation);
tweener->addTween(levelSelectorSlideInTween);
// Title screen zoom in tween
antHillZoomInTween = new Tween<float>(EaseFunction::LINEAR, 0.0f, 2.0f, 50.0f, -49.9f);
antHillZoomInTween->setUpdateCallback(std::bind(SurfaceCameraController::setTargetFocalDistance, surfaceCam, std::placeholders::_1));
tweener->addTween(antHillZoomInTween);
antHillFadeOutTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
antHillFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, blackoutImage, std::placeholders::_1));
antHillFadeOutTween->setEndCallback(std::bind(Application::changeState, this, mainMenuState));
tweener->addTween(antHillFadeOutTween);
// Build menu system
selectedMenuItemIndex = 0;
mainMenu = new Menu();
MenuItem* challengeItem = mainMenu->addItem();
challengeItem->setSelectedCallback(std::bind(UIElement::setTintColor, challengeLabel, selectedColor));
challengeItem->setDeselectedCallback(std::bind(UIElement::setTintColor, challengeLabel, deselectedColor));
challengeItem->setActivatedCallback(std::bind(Application::enterLevelSelection, this));
challengeLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, challengeItem->getIndex()));
challengeLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, challengeItem->getIndex()));
challengeLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, challengeItem->getIndex()));
MenuItem* experimentItem = mainMenu->addItem();
experimentItem->setSelectedCallback(std::bind(UIElement::setTintColor, experimentLabel, selectedColor));
experimentItem->setDeselectedCallback(std::bind(UIElement::setTintColor, experimentLabel, deselectedColor));
experimentItem->setActivatedCallback(std::bind(Application::enterMenu, this, 2));
experimentLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, experimentItem->getIndex()));
experimentLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, experimentItem->getIndex()));
experimentLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, experimentItem->getIndex()));
MenuItem* settingsItem = mainMenu->addItem();
settingsItem->setSelectedCallback(std::bind(UIElement::setTintColor, settingsLabel, selectedColor));
settingsItem->setDeselectedCallback(std::bind(UIElement::setTintColor, settingsLabel, deselectedColor));
settingsItem->setActivatedCallback(std::bind(Application::enterMenu, this, 3));
settingsLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, settingsItem->getIndex()));
settingsLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, settingsItem->getIndex()));
settingsLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, settingsItem->getIndex()));
MenuItem* quitItem = mainMenu->addItem();
quitItem->setSelectedCallback(std::bind(UIElement::setTintColor, quitLabel, selectedColor));
quitItem->setDeselectedCallback(std::bind(UIElement::setTintColor, quitLabel, deselectedColor));
quitItem->setActivatedCallback(std::bind(Application::close, this, EXIT_SUCCESS));
quitLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, quitItem->getIndex()));
quitLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, quitItem->getIndex()));
quitLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, quitItem->getIndex()));
experimentMenu = new Menu();
MenuItem* loadItem = experimentMenu->addItem();
loadItem->setSelectedCallback(std::bind(UIElement::setTintColor, loadLabel, selectedColor));
loadItem->setDeselectedCallback(std::bind(UIElement::setTintColor, loadLabel, deselectedColor));
loadItem->setActivatedCallback(std::bind(std::printf, "0\n"));
loadLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, loadItem->getIndex()));
loadLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, loadItem->getIndex()));
loadLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, loadItem->getIndex()));
MenuItem* newItem = experimentMenu->addItem();
newItem->setSelectedCallback(std::bind(UIElement::setTintColor, newLabel, selectedColor));
newItem->setDeselectedCallback(std::bind(UIElement::setTintColor, newLabel, deselectedColor));
newItem->setActivatedCallback(std::bind(std::printf, "bla\n"));
newLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, newItem->getIndex()));
newLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, newItem->getIndex()));
newLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, newItem->getIndex()));
MenuItem* experimentBackItem = experimentMenu->addItem();
experimentBackItem->setSelectedCallback(std::bind(UIElement::setTintColor, experimentBackLabel, selectedColor));
experimentBackItem->setDeselectedCallback(std::bind(UIElement::setTintColor, experimentBackLabel, deselectedColor));
experimentBackItem->setActivatedCallback(std::bind(Application::enterMenu, this, 0));
experimentBackLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, experimentBackItem->getIndex()));
experimentBackLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, experimentBackItem->getIndex()));
experimentBackLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, experimentBackItem->getIndex()));
settingsMenu = new Menu();
MenuItem* videoItem = settingsMenu->addItem();
videoItem->setSelectedCallback(std::bind(UIElement::setTintColor, videoLabel, selectedColor));
videoItem->setDeselectedCallback(std::bind(UIElement::setTintColor, videoLabel, deselectedColor));
videoItem->setActivatedCallback(std::bind(std::printf, "0\n"));
videoLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, videoItem->getIndex()));
videoLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, videoItem->getIndex()));
videoLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, videoItem->getIndex()));
MenuItem* audioItem = settingsMenu->addItem();
audioItem->setSelectedCallback(std::bind(UIElement::setTintColor, audioLabel, selectedColor));
audioItem->setDeselectedCallback(std::bind(UIElement::setTintColor, audioLabel, deselectedColor));
audioItem->setActivatedCallback(std::bind(std::printf, "1\n"));
audioLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, audioItem->getIndex()));
audioLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, audioItem->getIndex()));
audioLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, audioItem->getIndex()));
MenuItem* controlsItem = settingsMenu->addItem();
controlsItem->setSelectedCallback(std::bind(UIElement::setTintColor, controlsLabel, selectedColor));
controlsItem->setDeselectedCallback(std::bind(UIElement::setTintColor, controlsLabel, deselectedColor));
controlsItem->setActivatedCallback(std::bind(std::printf, "2\n"));
controlsLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, controlsItem->getIndex()));
controlsLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, controlsItem->getIndex()));
controlsLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, controlsItem->getIndex()));
MenuItem* gameItem = settingsMenu->addItem();
gameItem->setSelectedCallback(std::bind(UIElement::setTintColor, gameLabel, selectedColor));
gameItem->setDeselectedCallback(std::bind(UIElement::setTintColor, gameLabel, deselectedColor));
gameItem->setActivatedCallback(std::bind(std::printf, "3\n"));
gameLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, gameItem->getIndex()));
gameLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, gameItem->getIndex()));
gameLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, gameItem->getIndex()));
MenuItem* settingsBackItem = settingsMenu->addItem();
settingsBackItem->setSelectedCallback(std::bind(UIElement::setTintColor, settingsBackLabel, selectedColor));
settingsBackItem->setDeselectedCallback(std::bind(UIElement::setTintColor, settingsBackLabel, deselectedColor));
settingsBackItem->setActivatedCallback(std::bind(Application::enterMenu, this, 0));
settingsBackLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, this, settingsBackItem->getIndex()));
settingsBackLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, this, settingsBackItem->getIndex()));
settingsBackLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, this, settingsBackItem->getIndex()));
menuCount = 4;
menus = new Menu*[menuCount];
menus[0] = mainMenu;
menus[1] = challengeMenu;
menus[2] = experimentMenu;
menus[3] = settingsMenu;
menuContainers = new UIContainer*[menuCount];
menuContainers[0] = mainMenuContainer;
menuContainers[1] = challengeMenuContainer;
menuContainers[2] = experimentMenuContainer;
menuContainers[3] = settingsMenuContainer;
currentMenu = mainMenu;
currentMenuIndex = 0;
selectedMenuItemIndex = 0;
selectMenuItem(selectedMenuItemIndex);
currentLevel = 0;
levelSelectorMenu = new Menu();
for (int i = 0; i < 10; ++i)
{
MenuItem* levelSelectionItem = levelSelectorMenu->addItem();
levelSelectionItem->setSelectedCallback(std::bind(UIImage::setTexture, levelSelections[i], levelActiveTexture));
levelSelectionItem->setDeselectedCallback(std::bind(UIImage::setTexture, levelSelections[i], levelInactiveTexture));
levelSelectionItem->setActivatedCallback(std::bind(Application::loadLevel, this));
levelSelections[i]->setMouseOverCallback(std::bind(Application::selectLevel, this, levelSelectionItem->getIndex()));
levelSelections[i]->setMouseMovedCallback(std::bind(Application::selectLevel, this, levelSelectionItem->getIndex()));
levelSelections[i]->setMousePressedCallback(std::bind(Application::activateLevel, this, levelSelectionItem->getIndex()));
}
// Setup UI batch
uiBatch = new BillboardBatch();
uiBatch->resize(256);
uiBatcher = new UIBatcher();
// Setup UI render pass and compositor
uiPass.setRenderTarget(&defaultRenderTarget);
uiCompositor.addPass(&uiPass);
uiCompositor.load(nullptr);
// Setup UI camera
uiCamera.lookAt(glm::vec3(0), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));
uiCamera.setCompositor(&uiCompositor);
uiCamera.setCompositeIndex(0);
// Setup UI scene
uiLayer->addObject(uiBatch);
uiLayer->addObject(&uiCamera);
defaultRenderTarget.width = width;
defaultRenderTarget.height = height;
resizeUI();
return true;
}
bool Application::loadControls()
{
// Setup menu navigation controls
menuControlProfile = new ControlProfile(inputManager);
menuControlProfile->registerControl("menu_left", &menuLeft);
menuControlProfile->registerControl("menu_right", &menuRight);
menuControlProfile->registerControl("menu_up", &menuUp);
menuControlProfile->registerControl("menu_down", &menuDown);
menuControlProfile->registerControl("menu_select", &menuSelect);
menuControlProfile->registerControl("menu_cancel", &menuCancel);
menuControlProfile->registerControl("toggle_fullscreen", &toggleFullscreen);
menuControlProfile->registerControl("escape", &escape);
menuLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
menuLeft.bindKey(keyboard, SDL_SCANCODE_A);
menuRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
menuRight.bindKey(keyboard, SDL_SCANCODE_D);
menuUp.bindKey(keyboard, SDL_SCANCODE_UP);
menuUp.bindKey(keyboard, SDL_SCANCODE_W);
menuDown.bindKey(keyboard, SDL_SCANCODE_DOWN);
menuDown.bindKey(keyboard, SDL_SCANCODE_S);
menuSelect.bindKey(keyboard, SDL_SCANCODE_RETURN);
menuSelect.bindKey(keyboard, SDL_SCANCODE_SPACE);
menuSelect.bindKey(keyboard, SDL_SCANCODE_Z);
menuCancel.bindKey(keyboard, SDL_SCANCODE_BACKSPACE);
menuCancel.bindKey(keyboard, SDL_SCANCODE_X);
toggleFullscreen.bindKey(keyboard, SDL_SCANCODE_F11);
escape.bindKey(keyboard, SDL_SCANCODE_ESCAPE);
// Setup in-game controls
gameControlProfile = new ControlProfile(inputManager);
gameControlProfile->registerControl("camera-move-forward", &cameraMoveForward);
gameControlProfile->registerControl("camera-move-back", &cameraMoveBack);
gameControlProfile->registerControl("camera-move-left", &cameraMoveLeft);
gameControlProfile->registerControl("camera-move-right", &cameraMoveRight);
gameControlProfile->registerControl("camera-rotate-cw", &cameraRotateCW);
gameControlProfile->registerControl("camera-rotate-ccw", &cameraRotateCCW);
gameControlProfile->registerControl("camera-zoom-in", &cameraZoomIn);
gameControlProfile->registerControl("camera-zoom-out", &cameraZoomOut);
gameControlProfile->registerControl("camera-toggle-nest-view", &cameraToggleNestView);
gameControlProfile->registerControl("camera-toggle-overhead-view", &cameraToggleOverheadView);
gameControlProfile->registerControl("walk-forward", &walkForward);
gameControlProfile->registerControl("walk-back", &walkBack);
gameControlProfile->registerControl("turn-left", &turnLeft);
gameControlProfile->registerControl("turn-right", &turnRight);
cameraMoveForward.bindKey(keyboard, SDL_SCANCODE_W);
cameraMoveBack.bindKey(keyboard, SDL_SCANCODE_S);
cameraMoveLeft.bindKey(keyboard, SDL_SCANCODE_A);
cameraMoveRight.bindKey(keyboard, SDL_SCANCODE_D);
cameraRotateCW.bindKey(keyboard, SDL_SCANCODE_Q);
cameraRotateCCW.bindKey(keyboard, SDL_SCANCODE_E);
cameraZoomIn.bindKey(keyboard, SDL_SCANCODE_EQUALS);
cameraZoomOut.bindKey(keyboard, SDL_SCANCODE_MINUS);
cameraZoomIn.bindMouseWheelAxis(mouse, MouseWheelAxis::POSITIVE_Y);
cameraZoomOut.bindMouseWheelAxis(mouse, MouseWheelAxis::NEGATIVE_Y);
cameraToggleOverheadView.bindKey(keyboard, SDL_SCANCODE_R);
cameraToggleNestView.bindKey(keyboard, SDL_SCANCODE_F);
walkForward.bindKey(keyboard, SDL_SCANCODE_UP);
walkBack.bindKey(keyboard, SDL_SCANCODE_DOWN);
turnLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
turnRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
return true;
}
bool Application::loadGame()
{
// Load biosphere
biosphere.load("data/biomes/");
// Load campaign
campaign.load("data/levels/");
currentWorld = 1;
currentLevel = 1;
return true;
}
void Application::resizeUI()
{
// Adjust UI dimensions
@ -561,6 +1190,9 @@ void Application::enterMenu(std::size_t index)
// Make menu visible
menuContainers[currentMenuIndex]->setVisible(true);
// Make menu selector visible
menuSelectorLabel->setVisible(true);
}
void Application::exitMenu(std::size_t index)
@ -573,6 +1205,9 @@ void Application::exitMenu(std::size_t index)
menuFadeOutTween->setEndCallback(std::bind(UIElement::setVisible, menuContainers[currentMenuIndex], false));
menuFadeOutTween->reset();
menuFadeOutTween->start();
// Make menu selector invisible
menuSelectorLabel->setVisible(false);
}
void Application::selectMenuItem(std::size_t index)
@ -604,6 +1239,23 @@ void Application::activateMenuItem(std::size_t index)
menus[currentMenuIndex]->getItem(index)->activate();
}
void Application::enterLevelSelection()
{
exitMenu(0);
currentWorld = 1;
currentLevel = 1;
// Start menu slide-in tween
levelSelectorSlideInTween->setUpdateCallback(std::bind(UIElement::setTranslation, levelSelectorContainer, std::placeholders::_1));
levelSelectorSlideInTween->reset();
levelSelectorSlideInTween->start();
// Make menu visible and active
levelSelectorContainer->setVisible(true);
levelSelectorContainer->setActive(true);
}
void Application::selectLevel(std::size_t index)
{
if (index > levelSelectorMenu->getItemCount())

+ 80
- 64
src/application.hpp View File

@ -38,9 +38,10 @@ using namespace Emergent;
class Menu;
class ApplicationState;
class Colony;
class LoadingState;
class SplashState;
class TitleState;
class ExperimentState;
class MainMenuState;
class CameraController;
class SurfaceCameraController;
class TunnelCameraController;
@ -48,6 +49,9 @@ class LineBatcher;
class ModelLoader;
class MaterialLoader;
/**
* Encapsulates the state of the application.
*/
class Application
{
public:
@ -69,6 +73,14 @@ public:
void changeFullscreen();
void changeVerticalSync();
void saveUserSettings();
bool loadScene();
bool loadUI();
bool loadModels();
bool loadControls();
bool loadGame();
void resizeUI();
void enterMenu(std::size_t index);
@ -79,6 +91,8 @@ public:
void selectLevel(std::size_t index);
void activateLevel(std::size_t index);
void enterLevelSelection();
void loadLevel();
private:
@ -87,64 +101,82 @@ private:
int terminationCode;
public:
// SDL
SDL_Window* window;
SDL_GLContext context;
ModelInstance lensToolObject;
ModelInstance forcepsToolObject;
ModelInstance navigatorObject;
// Paths
std::string appDataPath;
std::string userDataPath;
std::string defaultSettingsFilename;
std::string userSettingsFilename;
// Settings
ParameterDict settings;
// Window
bool fullscreen;
int fullscreenWidth;
int fullscreenHeight;
int windowedWidth;
int windowedHeight;
int swapInterval;
int width;
int height;
// State machine
LoadingState* loadingState;
SplashState* splashState;
TitleState* titleState;
MainMenuState* mainMenuState;
// Scene
Scene scene;
SceneLayer* backgroundLayer;
SceneLayer* defaultLayer;
SceneLayer* uiLayer;
Camera camera;
Camera sunlightCamera;
Camera uiCamera;
Camera bgCamera;
DirectionalLight sunlight;
DirectionalLight fillLight;
DirectionalLight backLight;
Spotlight lensHotspot;
Spotlight lensFalloff;
ModelInstance lensToolObject;
ModelInstance forcepsToolObject;
ModelInstance navigatorObject;
ModelInstance antModelInstance;
ModelInstance antHillModelInstance;
// Graphics
Renderer renderer;
RenderTarget defaultRenderTarget;
RenderTarget shadowMapRenderTarget;
GLuint shadowFramebuffer;
GLuint shadowDepthTexture;
ShadowMapRenderPass shadowMapPass;
Compositor shadowCompositor;
Camera sunlightCamera;
RenderTarget defaultRenderTarget;
SoilRenderPass soilPass;
LightingRenderPass lightingPass;
DebugRenderPass debugPass;
Compositor shadowCompositor;
Compositor defaultCompositor;
Camera camera;
Scene scene;
BillboardBatch particleBatch;
Arcball arcball;
BillboardBatch* uiBatch;
UIBatcher* uiBatcher;
UIRenderPass uiPass;
Compositor uiCompositor;
BillboardBatch bgBatch;
Compositor bgCompositor;
VignetteRenderPass vignettePass;
TextureLoader* textureLoader;
MaterialLoader* materialLoader;
ModelLoader* modelLoader;
Renderer renderer;
int toolIndex;
std::string appDataPath;
std::string userDataPath;
ParameterDict settings;
std::string defaultSettingsFilename;
std::string userSettingsFilename;
bool fullscreen;
int fullscreenWidth;
int fullscreenHeight;
int windowedWidth;
int windowedHeight;
int swapInterval;
int width;
int height;
// Controls
InputManager* inputManager;
Keyboard* keyboard;
Mouse* mouse;
SplashState* splashState;
TitleState* titleState;
ExperimentState* experimentState;
ControlProfile* menuControlProfile;
Control menuLeft;
Control menuRight;
@ -154,7 +186,6 @@ public:
Control menuCancel;
Control toggleFullscreen;
Control escape;
ControlProfile* gameControlProfile;
Control cameraMoveForward;
Control cameraMoveBack;
@ -166,16 +197,15 @@ public:
Control cameraZoomOut;
Control cameraToggleOverheadView;
Control cameraToggleNestView;
bool cameraOverheadView;
bool cameraNestView;
Control walkForward;
Control walkBack;
Control turnLeft;
Control turnRight;
Arcball arcball;
// Misc
Timer frameTimer;
float dt;
// UI text
ParameterDict strings;
@ -224,29 +254,16 @@ public:
UILabel* pausedSettingsLabel;
UILabel* returnToMainMenuLabel;
UILabel* quitToDesktopLabel;
UIContainer* levelSelectorContainer;
UIImage* levelSelections[10];
UIImage* levelConnectors[9];
BillboardBatch* uiBatch;
UIBatcher* uiBatcher;
UIRenderPass uiPass;
Compositor uiCompositor;
Camera uiCamera;
Scene uiScene;
Camera bgCamera;
BillboardBatch bgBatch;
Compositor bgCompositor;
VignetteRenderPass vignettePass;
Scene bgScene;
// Animation
Tweener* tweener;
Tween<Vector4>* fadeInTween;
Tween<Vector4>* fadeOutTween;
Tween<Vector4>* splashFadeInTween;
Tween<float>* splashHangTween;
Tween<Vector4>* splashFadeOutTween;
Tween<Vector4>* titleFadeInTween;
Tween<Vector4>* titleFadeOutTween;
@ -254,10 +271,13 @@ public:
Tween<Vector4>* copyrightFadeOutTween;
Tween<Vector4>* anyKeyFadeInTween;
Tween<Vector4>* anyKeyFadeOutTween;
Tween<Vector4>* menuFadeInTween;
Tween<Vector4>* menuFadeOutTween;
Tween<Vector2>* menuSlideInTween;
Tween<Vector2>* levelSelectorSlideInTween;
Tween<float>* antHillZoomInTween;
Tween<Vector4>* antHillFadeOutTween;
// Menus
std::size_t menuCount;
@ -265,7 +285,6 @@ public:
int currentMenuIndex;
int selectedMenuItemIndex;
UIContainer** menuContainers;
Menu* currentMenu;
Menu* mainMenu;
Menu* challengeMenu;
@ -275,7 +294,7 @@ public:
// Models
Model* antModel;
ModelInstance* antModelInstance;
Model* antHillModel;
// Game variables
Campaign campaign;
@ -283,15 +302,12 @@ public:
int currentLevel;
Biosphere biosphere;
Terrain terrain;
Colony* colony;
SurfaceCameraController* surfaceCam;
TunnelCameraController* tunnelCam;
Plane clippingPlanes[5];
Vector3 clippingPlaneNormals[5];
Vector3 clippingPlaneOffsets[5];
AABB clippingPlaneAABBS[5];
bool cameraOverheadView;
bool cameraNestView;
int toolIndex;
// Debug
LineBatcher* lineBatcher;

+ 123
- 0
src/states/loading-state.cpp View File

@ -0,0 +1,123 @@
/*
* Copyright (C) 2017 Christopher J. Howard
*
* This file is part of Antkeeper Source Code.
*
* Antkeeper Source Code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper Source Code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "loading-state.hpp"
#include "../application.hpp"
#include "splash-state.hpp"
#include "title-state.hpp"
#include "main-menu-state.hpp"
LoadingState::LoadingState(Application* application):
ApplicationState(application)
{}
LoadingState::~LoadingState()
{}
void LoadingState::enter()
{
bool failure = false;
std::cout << "Loading controls... ";
if (!application->loadControls())
{
std::cout << "failed" << std::endl;
failure = true;
}
else
{
std::cout << "success" << std::endl;
}
std::cout << "Loading scene... ";
if (!application->loadScene())
{
std::cout << "failed" << std::endl;
failure = true;
}
else
{
std::cout << "success" << std::endl;
}
std::cout << "Loading UI... ";
if (!application->loadUI())
{
std::cout << "failed" << std::endl;
failure = true;
}
else
{
std::cout << "success" << std::endl;
}
std::cout << "Loading models... ";
if (!application->loadModels())
{
std::cout << "failed" << std::endl;
failure = true;
}
else
{
std::cout << "success" << std::endl;
}
std::cout << "Loading game... ";
if (!application->loadGame())
{
std::cout << "failed" << std::endl;
failure = true;
}
else
{
std::cout << "success" << std::endl;
}
if (failure)
{
application->close(EXIT_FAILURE);
}
}
void LoadingState::execute()
{
// Check for splash screen and title skip settings
bool skipSplash = false;
bool skipTitle = false;
application->settings.get("skip_splash", &skipSplash);
application->settings.get("skip_title", &skipTitle);
// Determine next state
ApplicationState* nextState = application->splashState;
if (skipSplash)
{
nextState = application->titleState;
if (skipTitle)
{
nextState = application->mainMenuState;
}
}
// Change state
application->changeState(nextState);
}
void LoadingState::exit()
{}

+ 39
- 0
src/states/loading-state.hpp View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2017 Christopher J. Howard
*
* This file is part of Antkeeper Source Code.
*
* Antkeeper Source Code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper Source Code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LOADING_STATE_HPP
#define LOADING_STATE_HPP
#include "../application-state.hpp"
/**
* Loads the application
*/
class LoadingState: public ApplicationState
{
public:
LoadingState(Application* application);
virtual ~LoadingState();
virtual void enter();
virtual void execute();
virtual void exit();
};
#endif // LOADING_STATE_HPP

+ 92
- 0
src/states/main-menu-state.cpp View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2017 Christopher J. Howard
*
* This file is part of Antkeeper Source Code.
*
* Antkeeper Source Code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper Source Code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main-menu-state.hpp"
#include "../application.hpp"
MainMenuState::MainMenuState(Application* application):
ApplicationState(application)
{}
MainMenuState::~MainMenuState()
{}
void MainMenuState::enter()
{
// Open main menu
application->enterMenu(0);
application->menuSelectorLabel->setVisible(true);
// Start fade-in
application->fadeInTween->start();
}
void MainMenuState::execute()
{
// Navigate menu
if (application->menuDown.isTriggered() && !application->menuDown.wasTriggered())
{
if (application->selectedMenuItemIndex < application->currentMenu->getItemCount() - 1)
{
application->selectMenuItem(application->selectedMenuItemIndex + 1);
}
else
{
application->selectMenuItem(0);
}
}
else if (application->menuUp.isTriggered() && !application->menuUp.wasTriggered())
{
if (application->selectedMenuItemIndex > 0)
{
application->selectMenuItem(application->selectedMenuItemIndex - 1);
}
else
{
application->selectMenuItem(application->currentMenu->getItemCount() - 1);
}
}
if (application->menuSelect.isTriggered() && !application->menuSelect.wasTriggered())
{
application->activateMenuItem(application->selectedMenuItemIndex);
}
else if (application->menuCancel.isTriggered() && !application->menuCancel.wasTriggered())
{
}
float lineHeight = application->menuFont->getMetrics().getHeight();
const UIContainer* container = application->menuContainers[application->currentMenuIndex];
application->menuSelectorLabel->setTranslation(
Vector2(container->getPosition().x - application->menuSelectorLabel->getDimensions().x * 1.5f,
container->getPosition().y + lineHeight * 0.5f - application->menuSelectorLabel->getDimensions().y * 0.5f + lineHeight * application->selectedMenuItemIndex));
}
void MainMenuState::exit()
{
}
void MainMenuState::mouseButtonPressed(int button, int x, int y)
{
}
void MainMenuState::mouseButtonReleased(int button, int x, int y)
{
}

+ 43
- 0
src/states/main-menu-state.hpp View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2017 Christopher J. Howard
*
* This file is part of Antkeeper Source Code.
*
* Antkeeper Source Code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper Source Code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MAIN_MENU_STATE_HPP
#define MAIN_MENU_STATE_HPP
#include "../application-state.hpp"
#include "../input.hpp"
#include <emergent/emergent.hpp>
using namespace Emergent;
class MainMenuState: public ApplicationState, public MouseButtonObserver
{
public:
MainMenuState(Application* application);
virtual ~MainMenuState();
virtual void enter();
virtual void execute();
virtual void exit();
virtual void mouseButtonPressed(int button, int x, int y);
virtual void mouseButtonReleased(int button, int x, int y);
};
#endif // MAIN_MENU_STATE_HPP

+ 12
- 652
src/states/splash-state.cpp View File

@ -18,20 +18,8 @@
*/
#include "splash-state.hpp"
#include "title-state.hpp"
#include "experiment-state.hpp"
#include "../application.hpp"
#include "../camera-controller.hpp"
#include "../debug.hpp"
#include "../model-loader.hpp"
#include <iostream>
#include <cstdio>
#include <SDL.h>
const float blankDuration = 0.0f;
const float fadeInDuration = 0.5f;
const float hangDuration = 1.0f;
const float fadeOutDuration = 0.5f;
#include "title-state.hpp"
SplashState::SplashState(Application* application):
ApplicationState(application)
@ -42,574 +30,28 @@ SplashState::~SplashState()
void SplashState::enter()
{
std::cout << "Entering SplashState..." << std::endl;
application->scene.addLayer();
application->uiScene.addLayer();
// Debug
application->lineBatcher = new LineBatcher(4096);
BillboardBatch* lineBatch = application->lineBatcher->getBatch();
lineBatch->setAlignment(&application->camera, BillboardAlignmentMode::CYLINDRICAL);
lineBatch->setAlignmentVector(Vector3(1, 0, 0));
application->scene.getLayer(0)->addObject(lineBatch);
// Load menu font
application->menuFont = new Font(512, 512);
FontLoader* fontLoader = new FontLoader();
if (!fontLoader->load("data/fonts/Varela-Regular.ttf", application->fontSizePX, application->menuFont))
{
std::cerr << "Failed to load font" << std::endl;
}
delete fontLoader;
// Load UI textures
application->textureLoader->setGamma(1.0f);
application->textureLoader->setCubemap(false);
application->textureLoader->setMipmapChain(false);
application->textureLoader->setMaxAnisotropy(1.0f);
application->splashTexture = application->textureLoader->load("data/textures/splash.png");
application->titleTexture = application->textureLoader->load("data/textures/title.png");
application->levelActiveTexture = application->textureLoader->load("data/textures/ui-level-active.png");
application->levelInactiveTexture = application->textureLoader->load("data/textures/ui-level-inactive.png");
application->levelConnectorTexture = application->textureLoader->load("data/textures/ui-level-connector.png");
// Get UI strings
std::string pressAnyKeyString;
std::string backString;
std::string challengeString;
std::string experimentString;
std::string settingsString;
std::string quitString;
std::string loadString;
std::string newString;
std::string videoString;
std::string audioString;
std::string controlsString;
std::string gameString;
std::string resumeString;
std::string returnToMainMenuString;
std::string quitToDesktopString;
application->strings.get("press-any-key", &pressAnyKeyString);
application->strings.get("back", &backString);
application->strings.get("challenge", &challengeString);
application->strings.get("experiment", &experimentString);
application->strings.get("settings", &settingsString);
application->strings.get("quit", &quitString);
application->strings.get("load", &loadString);
application->strings.get("new", &newString);
application->strings.get("video", &videoString);
application->strings.get("audio", &audioString);
application->strings.get("controls", &controlsString);
application->strings.get("game", &gameString);
application->strings.get("resume", &resumeString);
application->strings.get("return-to-main-menu", &returnToMainMenuString);
application->strings.get("quit-to-desktop", &quitToDesktopString);
// Colors
application->selectedColor = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
application->deselectedColor = Vector4(0.0f, 0.0f, 0.0f, 0.35f);
// Build UI
application->uiRootElement = new UIContainer();
application->uiRootElement->setDimensions(Vector2(application->width, application->height));
application->mouse->addMouseMotionObserver(application->uiRootElement);
application->mouse->addMouseButtonObserver(application->uiRootElement);
application->blackoutImage = new UIImage();
application->blackoutImage->setDimensions(Vector2(application->width, application->height));
application->blackoutImage->setLayerOffset(99);
application->blackoutImage->setTintColor(Vector4(0.0f, 0.0f, 0.0f, 1.0f));
application->blackoutImage->setVisible(false);
application->uiRootElement->addChild(application->blackoutImage);
application->splashImage = new UIImage();
application->splashImage->setAnchor(Anchor::CENTER);
application->splashImage->setDimensions(Vector2(application->splashTexture->getWidth(), application->splashTexture->getHeight()));
application->splashImage->setTexture(application->splashTexture);
application->splashImage->setVisible(false);
application->uiRootElement->addChild(application->splashImage);
application->titleImage = new UIImage();
application->titleImage->setAnchor(Vector2(0.5f, 0.0f));
application->titleImage->setDimensions(Vector2(application->titleTexture->getWidth(), application->titleTexture->getHeight()));
application->titleImage->setTranslation(Vector2(0.0f, (int)(application->height * (1.0f / 3.0f) - application->titleTexture->getHeight())));
application->titleImage->setTexture(application->titleTexture);
application->titleImage->setVisible(false);
application->uiRootElement->addChild(application->titleImage);
/*
application->copyrightImage = new UIImage();
application->copyrightImage->setAnchor(Vector2(0.5f, 1.0f));
application->copyrightImage->setDimensions(Vector2(copyrightTextureWidth, copyrightTextureHeight));
application->copyrightImage->setTranslation(Vector2(-.5f, (int)(-application->height * (1.0f / 10.0f) - copyrightTextureHeight * 0.5f)));
application->copyrightImage->setTexture(nullptr);
application->copyrightImage->setVisible(false);
application->uiRootElement->addChild(application->copyrightImage);
*/
application->anyKeyLabel = new UILabel();
application->anyKeyLabel->setAnchor(Vector2(0.5f, 1.0f));
application->anyKeyLabel->setFont(application->menuFont);
application->anyKeyLabel->setTranslation(Vector2(0.0f, (int)(-application->height * (1.0f / 3.0f)/* - application->menuFont->getMetrics().getHeight() * 0.5f*/)));
application->anyKeyLabel->setText(pressAnyKeyString);
application->anyKeyLabel->setVisible(false);
application->uiRootElement->addChild(application->anyKeyLabel);
application->menuSelectorLabel = new UILabel();
application->menuSelectorLabel->setAnchor(Anchor::TOP_LEFT);
application->menuSelectorLabel->setFont(application->menuFont);
application->menuSelectorLabel->setText("<");
application->menuSelectorLabel->setTintColor(application->selectedColor);
/*
application->menuSelectorLabel = new UIImage();
application->menuSelectorLabel->setAnchor(Anchor::TOP_LEFT);
application->menuSelectorLabel->setDimensions(Vector2(selectorTextureWidth, selectorTextureHeight));
application->menuSelectorLabel->setTextureID(selectorTextureID);
*/
application->menuSelectorLabel->setVisible(false);
application->uiRootElement->addChild(application->menuSelectorLabel);
application->mainMenuContainer = new UIContainer();
application->mainMenuContainer->setDimensions(Vector2(application->width, application->menuFont->getMetrics().getHeight() * 4));
application->mainMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
application->mainMenuContainer->setVisible(false);
application->mainMenuContainer->setActive(false);
application->uiRootElement->addChild(application->mainMenuContainer);
application->challengeLabel = new UILabel();
application->challengeLabel->setFont(application->menuFont);
application->challengeLabel->setText(challengeString);
application->challengeLabel->setTintColor(application->deselectedColor);
application->experimentLabel = new UILabel();
application->experimentLabel->setFont(application->menuFont);
application->experimentLabel->setText(experimentString);
application->experimentLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight()));
application->experimentLabel->setTintColor(application->deselectedColor);
application->settingsLabel = new UILabel();
application->settingsLabel->setFont(application->menuFont);
application->settingsLabel->setText(settingsString);
application->settingsLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 2));
application->settingsLabel->setTintColor(application->deselectedColor);
application->quitLabel = new UILabel();
application->quitLabel->setFont(application->menuFont);
application->quitLabel->setText(quitString);
application->quitLabel->setTintColor(application->deselectedColor);
application->quitLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 3));
application->mainMenuContainer->addChild(application->challengeLabel);
application->mainMenuContainer->addChild(application->experimentLabel);
application->mainMenuContainer->addChild(application->settingsLabel);
application->mainMenuContainer->addChild(application->quitLabel);
application->challengeMenuContainer = new UIContainer();
application->challengeMenuContainer->setDimensions(Vector2(application->width, application->menuFont->getMetrics().getHeight() * 4));
application->challengeMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
application->challengeMenuContainer->setVisible(false);
application->challengeMenuContainer->setActive(false);
application->uiRootElement->addChild(application->challengeMenuContainer);
application->experimentMenuContainer = new UIContainer();
application->experimentMenuContainer->setDimensions(Vector2(application->width, application->menuFont->getMetrics().getHeight() * 3));
application->experimentMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
application->experimentMenuContainer->setVisible(false);
application->experimentMenuContainer->setActive(false);
application->uiRootElement->addChild(application->experimentMenuContainer);
application->loadLabel = new UILabel();
application->loadLabel->setFont(application->menuFont);
application->loadLabel->setText(loadString);
application->loadLabel->setTintColor(application->deselectedColor);
application->loadLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 0));
application->experimentMenuContainer->addChild(application->loadLabel);
application->newLabel = new UILabel();
application->newLabel->setFont(application->menuFont);
application->newLabel->setText(newString);
application->newLabel->setTintColor(application->deselectedColor);
application->newLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 1));
application->experimentMenuContainer->addChild(application->newLabel);
application->experimentBackLabel = new UILabel();
application->experimentBackLabel->setFont(application->menuFont);
application->experimentBackLabel->setText(backString);
application->experimentBackLabel->setTintColor(application->deselectedColor);
application->experimentBackLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 2));
application->experimentMenuContainer->addChild(application->experimentBackLabel);
application->settingsMenuContainer = new UIContainer();
application->settingsMenuContainer->setDimensions(Vector2(application->width, application->menuFont->getMetrics().getHeight() * 5));
application->settingsMenuContainer->setAnchor(Vector2(0.0f, 0.5f));
application->settingsMenuContainer->setVisible(false);
application->settingsMenuContainer->setActive(false);
application->uiRootElement->addChild(application->settingsMenuContainer);
application->videoLabel = new UILabel();
application->videoLabel->setFont(application->menuFont);
application->videoLabel->setText(videoString);
application->videoLabel->setTintColor(application->deselectedColor);
application->videoLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 0));
application->settingsMenuContainer->addChild(application->videoLabel);
application->audioLabel = new UILabel();
application->audioLabel->setFont(application->menuFont);
application->audioLabel->setText(audioString);
application->audioLabel->setTintColor(application->deselectedColor);
application->audioLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 1));
application->settingsMenuContainer->addChild(application->audioLabel);
application->controlsLabel = new UILabel();
application->controlsLabel->setFont(application->menuFont);
application->controlsLabel->setText(controlsString);
application->controlsLabel->setTintColor(application->deselectedColor);
application->controlsLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 2));
application->settingsMenuContainer->addChild(application->controlsLabel);
application->gameLabel = new UILabel();
application->gameLabel->setFont(application->menuFont);
application->gameLabel->setText(gameString);
application->gameLabel->setTintColor(application->deselectedColor);
application->gameLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 3));
application->settingsMenuContainer->addChild(application->gameLabel);
application->settingsBackLabel = new UILabel();
application->settingsBackLabel->setFont(application->menuFont);
application->settingsBackLabel->setText(backString);
application->settingsBackLabel->setTintColor(application->deselectedColor);
application->settingsBackLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 4));
application->settingsMenuContainer->addChild(application->settingsBackLabel);
application->pauseMenuContainer = new UIContainer();
application->pauseMenuContainer->setDimensions(Vector2(application->width, application->menuFont->getMetrics().getHeight() * 6));
application->pauseMenuContainer->setAnchor(Anchor::CENTER);
application->pauseMenuContainer->setVisible(false);
application->pauseMenuContainer->setActive(false);
application->uiRootElement->addChild(application->pauseMenuContainer);
application->pausedResumeLabel = new UILabel();
application->pausedResumeLabel->setFont(application->menuFont);
application->pausedResumeLabel->setText(resumeString);
application->pausedResumeLabel->setTintColor(application->deselectedColor);
application->pausedResumeLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 0));
application->pauseMenuContainer->addChild(application->pausedResumeLabel);
application->returnToMainMenuLabel = new UILabel();
application->returnToMainMenuLabel->setFont(application->menuFont);
application->returnToMainMenuLabel->setText(returnToMainMenuString);
application->returnToMainMenuLabel->setTintColor(application->deselectedColor);
application->returnToMainMenuLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 1));
application->pauseMenuContainer->addChild(application->returnToMainMenuLabel);
application->quitToDesktopLabel = new UILabel();
application->quitToDesktopLabel->setFont(application->menuFont);
application->quitToDesktopLabel->setText(quitToDesktopString);
application->quitToDesktopLabel->setTintColor(application->deselectedColor);
application->quitToDesktopLabel->setTranslation(Vector2(0.0f, application->menuFont->getMetrics().getHeight() * 2));
application->pauseMenuContainer->addChild(application->quitToDesktopLabel);
// Level selector
application->levelSelectorContainer = new UIContainer();
application->levelSelectorContainer->setDimensions(Vector2(application->levelActiveTexture->getWidth() * 10 + 48 * 9, application->levelActiveTexture->getHeight()));
application->levelSelectorContainer->setAnchor(Vector2(0.5f, 1.0f));
application->levelSelectorContainer->setTranslation(Vector2(0.0f, -application->levelActiveTexture->getHeight()));
application->levelSelectorContainer->setVisible(true);
application->levelSelectorContainer->setActive(true);
application->uiRootElement->addChild(application->levelSelectorContainer);
for (int i = 0; i < 10; ++i)
{
application->levelSelections[i] = new UIImage();
application->levelSelections[i]->setAnchor(Vector2(0.0f, 0.5f));
application->levelSelections[i]->setDimensions(Vector2(application->levelActiveTexture->getWidth(), application->levelActiveTexture->getHeight()));
application->levelSelections[i]->setTranslation(Vector2(i * 96.0f, 0.0f));
application->levelSelections[i]->setTexture(application->levelInactiveTexture);
application->levelSelections[i]->setVisible(true);
application->levelSelectorContainer->addChild(application->levelSelections[i]);
if (i < 9)
{
application->levelConnectors[i] = new UIImage();
application->levelConnectors[i]->setAnchor(Vector2(0.0f, 0.5f));
application->levelConnectors[i]->setDimensions(Vector2(application->levelConnectorTexture->getWidth(), application->levelConnectorTexture->getHeight()));
application->levelConnectors[i]->setTranslation(Vector2((i + 1) * 96.0f - 50.0f, 0.0f));
application->levelConnectors[i]->setTexture(application->levelConnectorTexture);
application->levelConnectors[i]->setVisible(true);
application->levelSelectorContainer->addChild(application->levelConnectors[i]);
}
}
application->titleImage = new UIImage();
application->titleImage->setAnchor(Vector2(0.5f, 0.0f));
application->titleImage->setDimensions(Vector2(application->titleTexture->getWidth(), application->titleTexture->getHeight()));
application->titleImage->setTranslation(Vector2(0.0f, (int)(application->height * (1.0f / 3.0f) - application->titleTexture->getHeight())));
application->titleImage->setTexture(application->titleTexture);
application->titleImage->setVisible(false);
application->uiRootElement->addChild(application->titleImage);
/*
UIContainer* pauseMenuContainer;
UILabel* pausedResumeLabel;
UILabel* pausedSaveLabel;
UILabel* pausedNewLabel;
UILabel* pausedSettingsLabel;
UILabel* returnToMainMenuLabel;
UILabel* quitToDesktopLabel;*/
// Setup UI batch
application->uiBatch = new BillboardBatch();
application->uiBatch->resize(256);
application->uiBatcher = new UIBatcher();
// Setup UI render pass and compositor
application->uiPass.setRenderTarget(&application->defaultRenderTarget);
application->uiCompositor.addPass(&application->uiPass);
application->uiCompositor.load(nullptr);
// Setup UI camera
application->uiCamera.lookAt(glm::vec3(0), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));
application->uiCamera.setCompositor(&application->uiCompositor);
application->uiCamera.setCompositeIndex(0);
// Setup UI scene
application->uiScene.getLayer(0)->addObject(application->uiBatch);
application->uiScene.getLayer(0)->addObject(&application->uiCamera);
// Setup tweening
application->tweener = new Tweener();
application->fadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
application->fadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->blackoutImage, std::placeholders::_1));
application->tweener->addTween(application->fadeInTween);
application->fadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
application->fadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->blackoutImage, std::placeholders::_1));
application->tweener->addTween(application->fadeOutTween);
application->splashFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
application->splashFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->splashImage, std::placeholders::_1));
application->tweener->addTween(application->splashFadeInTween);
application->splashFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
application->splashFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->splashImage, std::placeholders::_1));
application->tweener->addTween(application->splashFadeOutTween);
application->titleFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 2.0f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
application->titleFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->titleImage, std::placeholders::_1));
application->tweener->addTween(application->titleFadeInTween);
application->titleFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.25f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
application->titleFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->titleImage, std::placeholders::_1));
application->tweener->addTween(application->titleFadeOutTween);
application->copyrightFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 1.0f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
application->copyrightFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->copyrightImage, std::placeholders::_1));
application->tweener->addTween(application->copyrightFadeInTween);
application->copyrightFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.25f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
application->copyrightFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->copyrightImage, std::placeholders::_1));
application->tweener->addTween(application->copyrightFadeOutTween);
application->anyKeyFadeInTween = new Tween<Vector4>(EaseFunction::LINEAR, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
application->anyKeyFadeInTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->anyKeyLabel, std::placeholders::_1));
application->tweener->addTween(application->anyKeyFadeInTween);
application->anyKeyFadeOutTween = new Tween<Vector4>(EaseFunction::LINEAR, 0.0f, 1.5f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
application->anyKeyFadeOutTween->setUpdateCallback(std::bind(UIElement::setTintColor, application->anyKeyLabel, std::placeholders::_1));
application->tweener->addTween(application->anyKeyFadeOutTween);
float menuFadeInDuration = 0.15f;
Vector4 menuFadeInStartColor = Vector4(1.0f, 1.0f, 1.0f, 0.0f);
Vector4 menuFadeInDeltaColor = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
float menuFadeOutDuration = 0.15f;
Vector4 menuFadeOutStartColor = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 menuFadeOutDeltaColor = Vector4(0.0f, 0.0f, 0.0f, -1.0f);
float menuSlideInDuration = 0.35f;
Vector2 menuSlideInStartTranslation = Vector2(-64.0f, 0.0f);
Vector2 menuSlideInDeltaTranslation = Vector2(128.0f, 0.0f);
application->menuFadeInTween = new Tween<Vector4>(EaseFunction::OUT_QUINT, 0.0f, menuFadeInDuration, menuFadeInStartColor, menuFadeInDeltaColor);
application->tweener->addTween(application->menuFadeInTween);
application->menuFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_QUINT, 0.0f, menuFadeOutDuration, menuFadeOutStartColor, menuFadeOutDeltaColor);
application->tweener->addTween(application->menuFadeOutTween);
application->menuSlideInTween = new Tween<Vector2>(EaseFunction::OUT_QUINT, 0.0f, menuSlideInDuration, menuSlideInStartTranslation, menuSlideInDeltaTranslation);
application->tweener->addTween(application->menuSlideInTween);
// Link tweens
application->anyKeyFadeInTween->setEndCallback(std::bind(TweenBase::start, application->anyKeyFadeOutTween));
application->anyKeyFadeOutTween->setEndCallback(std::bind(TweenBase::start, application->anyKeyFadeInTween));
// Menus
application->selectedMenuItemIndex = 0;
application->mainMenu = new Menu();
MenuItem* challengeItem = application->mainMenu->addItem();
challengeItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->challengeLabel, application->selectedColor));
challengeItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->challengeLabel, application->deselectedColor));
challengeItem->setActivatedCallback(std::bind(std::printf, "0\n"));
application->challengeLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, challengeItem->getIndex()));
application->challengeLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, challengeItem->getIndex()));
application->challengeLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, challengeItem->getIndex()));
MenuItem* experimentItem = application->mainMenu->addItem();
experimentItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->experimentLabel, application->selectedColor));
experimentItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->experimentLabel, application->deselectedColor));
experimentItem->setActivatedCallback(std::bind(Application::enterMenu, application, 2));
application->experimentLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, experimentItem->getIndex()));
application->experimentLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, experimentItem->getIndex()));
application->experimentLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, experimentItem->getIndex()));
MenuItem* settingsItem = application->mainMenu->addItem();
settingsItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->settingsLabel, application->selectedColor));
settingsItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->settingsLabel, application->deselectedColor));
settingsItem->setActivatedCallback(std::bind(Application::enterMenu, application, 3));
application->settingsLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, settingsItem->getIndex()));
application->settingsLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, settingsItem->getIndex()));
application->settingsLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, settingsItem->getIndex()));
MenuItem* quitItem = application->mainMenu->addItem();
quitItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->quitLabel, application->selectedColor));
quitItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->quitLabel, application->deselectedColor));
quitItem->setActivatedCallback(std::bind(Application::close, application, EXIT_SUCCESS));
application->quitLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, quitItem->getIndex()));
application->quitLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, quitItem->getIndex()));
application->quitLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, quitItem->getIndex()));
application->experimentMenu = new Menu();
MenuItem* loadItem = application->experimentMenu->addItem();
loadItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->loadLabel, application->selectedColor));
loadItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->loadLabel, application->deselectedColor));
loadItem->setActivatedCallback(std::bind(std::printf, "0\n"));
application->loadLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, loadItem->getIndex()));
application->loadLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, loadItem->getIndex()));
application->loadLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, loadItem->getIndex()));
MenuItem* newItem = application->experimentMenu->addItem();
newItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->newLabel, application->selectedColor));
newItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->newLabel, application->deselectedColor));
newItem->setActivatedCallback(std::bind(Application::changeState, application, application->experimentState));
application->newLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, newItem->getIndex()));
application->newLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, newItem->getIndex()));
application->newLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, newItem->getIndex()));
MenuItem* experimentBackItem = application->experimentMenu->addItem();
experimentBackItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->experimentBackLabel, application->selectedColor));
experimentBackItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->experimentBackLabel, application->deselectedColor));
experimentBackItem->setActivatedCallback(std::bind(Application::enterMenu, application, 0));
application->experimentBackLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, experimentBackItem->getIndex()));
application->experimentBackLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, experimentBackItem->getIndex()));
application->experimentBackLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, experimentBackItem->getIndex()));
application->settingsMenu = new Menu();
MenuItem* videoItem = application->settingsMenu->addItem();
videoItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->videoLabel, application->selectedColor));
videoItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->videoLabel, application->deselectedColor));
videoItem->setActivatedCallback(std::bind(std::printf, "0\n"));
application->videoLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, videoItem->getIndex()));
application->videoLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, videoItem->getIndex()));
application->videoLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, videoItem->getIndex()));
MenuItem* audioItem = application->settingsMenu->addItem();
audioItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->audioLabel, application->selectedColor));
audioItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->audioLabel, application->deselectedColor));
audioItem->setActivatedCallback(std::bind(std::printf, "1\n"));
application->audioLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, audioItem->getIndex()));
application->audioLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, audioItem->getIndex()));
application->audioLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, audioItem->getIndex()));
MenuItem* controlsItem = application->settingsMenu->addItem();
controlsItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->controlsLabel, application->selectedColor));
controlsItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->controlsLabel, application->deselectedColor));
controlsItem->setActivatedCallback(std::bind(std::printf, "2\n"));
application->controlsLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, controlsItem->getIndex()));
application->controlsLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, controlsItem->getIndex()));
application->controlsLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, controlsItem->getIndex()));
MenuItem* gameItem = application->settingsMenu->addItem();
gameItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->gameLabel, application->selectedColor));
gameItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->gameLabel, application->deselectedColor));
gameItem->setActivatedCallback(std::bind(std::printf, "3\n"));
application->gameLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, gameItem->getIndex()));
application->gameLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, gameItem->getIndex()));
application->gameLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, gameItem->getIndex()));
MenuItem* settingsBackItem = application->settingsMenu->addItem();
settingsBackItem->setSelectedCallback(std::bind(UIElement::setTintColor, application->settingsBackLabel, application->selectedColor));
settingsBackItem->setDeselectedCallback(std::bind(UIElement::setTintColor, application->settingsBackLabel, application->deselectedColor));
settingsBackItem->setActivatedCallback(std::bind(Application::enterMenu, application, 0));
application->settingsBackLabel->setMouseOverCallback(std::bind(Application::selectMenuItem, application, settingsBackItem->getIndex()));
application->settingsBackLabel->setMouseMovedCallback(std::bind(Application::selectMenuItem, application, settingsBackItem->getIndex()));
application->settingsBackLabel->setMousePressedCallback(std::bind(Application::activateMenuItem, application, settingsBackItem->getIndex()));
application->menuCount = 4;
application->menus = new Menu*[application->menuCount];
application->menus[0] = application->mainMenu;
application->menus[1] = application->challengeMenu;
application->menus[2] = application->experimentMenu;
application->menus[3] = application->settingsMenu;
application->menuContainers = new UIContainer*[application->menuCount];
application->menuContainers[0] = application->mainMenuContainer;
application->menuContainers[1] = application->challengeMenuContainer;
application->menuContainers[2] = application->experimentMenuContainer;
application->menuContainers[3] = application->settingsMenuContainer;
application->currentMenu = application->mainMenu;
application->currentMenuIndex = 0;
application->selectedMenuItemIndex = 0;
application->selectMenuItem(application->selectedMenuItemIndex);
application->currentLevel = 0;
application->levelSelectorMenu = new Menu();
for (int i = 0; i < 10; ++i)
{
MenuItem* levelSelectionItem = application->levelSelectorMenu->addItem();
levelSelectionItem->setSelectedCallback(std::bind(UIImage::setTexture, application->levelSelections[i], application->levelActiveTexture));
levelSelectionItem->setDeselectedCallback(std::bind(UIImage::setTexture, application->levelSelections[i], application->levelInactiveTexture));
levelSelectionItem->setActivatedCallback(std::bind(Application::loadLevel, application));
application->levelSelections[i]->setMouseOverCallback(std::bind(Application::selectLevel, application, levelSelectionItem->getIndex()));
application->levelSelections[i]->setMouseMovedCallback(std::bind(Application::selectLevel, application, levelSelectionItem->getIndex()));
application->levelSelections[i]->setMousePressedCallback(std::bind(Application::activateLevel, application, levelSelectionItem->getIndex()));
}
// Models
application->antModel = application->modelLoader->load("data/models/debug-worker.mdl");
// Model instances
application->antModelInstance = new ModelInstance();
// Allocate game variables
application->surfaceCam = new SurfaceCameraController();
application->tunnelCam = new TunnelCameraController();
// Load biosphere
application->biosphere.load("data/biomes/");
// Load campaign
application->campaign.load("data/levels/");
application->currentWorld = 1;
application->currentLevel = 1;
// Setup screen fade-in transition
fadeIn = false;
fadeOut = false;
// Check for splash screen skip setting
skip = false;
application->settings.get("skip_splash", &skip);
// Add window observer and set layout
application->inputManager->addWindowObserver(this);
windowResized(application->width, application->height);
// Start timer
stateTime = 0.0f;
application->frameTimer.reset();
application->frameTimer.start();
application->splashImage->setVisible(true);
application->splashFadeInTween->start();
}
void SplashState::execute()
{
// Calculate delta time (in seconds)
float dt = static_cast<float>(application->frameTimer.microseconds().count()) / 1000000.0f;
application->frameTimer.reset();
// Add dt to state time
stateTime += dt;
// Listen for splash screen skip
InputEvent event;
application->inputManager->listen(&event);
if (skip || event.type != InputEvent::Type::NONE)
if (event.type != InputEvent::Type::NONE)
{
// Update control profile and input manager
application->menuControlProfile->update();
application->inputManager->update();
// Check if application was closed
if (application->escape.isTriggered())
if (application->inputManager->wasClosed() || application->escape.isTriggered())
{
application->close(EXIT_SUCCESS);
return;
}
// Check if fullscreen was toggled
else if (application->toggleFullscreen.isTriggered() && !application->toggleFullscreen.wasTriggered())
{
@ -621,102 +63,20 @@ void SplashState::execute()
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(application->window);
// Stop splash tweens
application->splashFadeInTween->stop();
application->splashHangTween->stop();
application->splashFadeOutTween->stop();
// Change to title state
application->changeState(application->titleState);
return;
}
}
// Start fade-in
if (!fadeIn && stateTime >= blankDuration)
{
// Begin fade-in
fadeIn = true;
application->splashImage->setVisible(true);
application->splashFadeInTween->start();
}
// Begin fade-out
if (!fadeOut && stateTime >= blankDuration + application->splashFadeInTween->getDuration() + hangDuration)
{
fadeOut = true;
application->splashFadeOutTween->start();
}
// Next state
if (fadeOut && application->splashFadeOutTween->isStopped())
{
application->splashImage->setVisible(false);
application->changeState(application->titleState);
return;
}
// Update input
application->inputManager->update();
// Update menu controls
application->menuControlProfile->update();
// Check if application was closed
if (application->inputManager->wasClosed() || application->escape.isTriggered())
{
application->close(EXIT_SUCCESS);
return;
}
// Perform tweening
application->tweener->update(dt);
// Update UI
application->uiRootElement->update();
// Clear to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Form billboard batch for UI then render UI scene
application->uiBatcher->batch(application->uiBatch, application->uiRootElement);
application->renderer.render(application->uiScene);
// Swap buffers
SDL_GL_SwapWindow(application->window);
}
void SplashState::exit()
{
std::cout << "Exiting SplashState..." << std::endl;
// Hide splash screen
application->splashImage->setVisible(false);
application->inputManager->removeWindowObserver(this);
}
void SplashState::windowClosed()
{
application->close(EXIT_SUCCESS);
}
void SplashState::windowResized(int width, int height)
{
// Update application dimensions
application->width = width;
application->height = height;
if (application->fullscreen)
{
application->fullscreenWidth = width;
application->fullscreenHeight = height;
}
else
{
application->windowedWidth = width;
application->windowedHeight = height;
}
// Setup default render target
application->defaultRenderTarget.width = application->width;
application->defaultRenderTarget.height = application->height;
// Resize UI
application->resizeUI();
}

+ 1
- 10
src/states/splash-state.hpp View File

@ -29,7 +29,7 @@ using namespace Emergent;
/**
* Displays a splash screen.
*/
class SplashState: public ApplicationState, public WindowObserver
class SplashState: public ApplicationState
{
public:
SplashState(Application* application);
@ -38,15 +38,6 @@ public:
virtual void enter();
virtual void execute();
virtual void exit();
void windowClosed();
void windowResized(int width, int height);
private:
float stateTime;
bool fadeIn;
bool fadeOut;
bool skip;
};
#endif // SPLASH_STATE_HPP

+ 26
- 264
src/states/title-state.cpp View File

@ -18,7 +18,7 @@
*/
#include "title-state.hpp"
#include "experiment-state.hpp"
#include "main-menu-state.hpp"
#include "../application.hpp"
#include "../camera-controller.hpp"
#include <iostream>
@ -40,16 +40,11 @@ TitleState::~TitleState()
{}
void TitleState::enter()
{
std::cout << "Entering TitleState..." << std::endl;
{
// Setup screen fade-in transition
fadeIn = false;
fadeOut = false;
application->antModelInstance->setModel(application->antModel);
application->antModelInstance->setTransform(Transform::getIdentity());
// BG
application->bgBatch.resize(1);
BillboardBatch::Range* bgRange = application->bgBatch.addRange();
@ -69,9 +64,11 @@ void TitleState::enter()
application->bgCamera.setCompositor(&application->bgCompositor);
application->bgCamera.setCompositeIndex(0);
application->bgScene.addLayer();
application->bgScene.getLayer(0)->addObject(&application->bgCamera);
application->bgScene.getLayer(0)->addObject(&application->bgBatch);
application->backgroundLayer->addObject(&application->bgCamera);
application->backgroundLayer->addObject(&application->bgBatch);
// Title ant hill
application->defaultLayer->addObject(&application->antHillModelInstance);
// Setup lighting
application->sunlight.setColor(glm::vec3(1.0f));
@ -88,8 +85,8 @@ void TitleState::enter()
terrainSurface.setTranslation(Vector3(0, 0, 0));
terrainSubsurface.setModel(application->terrain.getSubsurfaceModel());
terrainSubsurface.setTranslation(Vector3(0, 0, 0));
application->scene.getLayer(0)->addObject(&terrainSurface);
application->scene.getLayer(0)->addObject(&terrainSubsurface);
//application->defaultLayer->addObject(&terrainSurface);
//application->defaultLayer->addObject(&terrainSubsurface);
navmesh = application->terrain.getSurfaceNavmesh();
// Load level
@ -111,98 +108,47 @@ void TitleState::enter()
application->camera.setCompositeIndex(0);
// Setup scene
DirectionalLight* lightA = new DirectionalLight();
DirectionalLight* lightB = new DirectionalLight();
DirectionalLight* lightC = new DirectionalLight();
lightA->setColor(glm::vec3(1.0f));
lightB->setColor(glm::vec3(0.25f));
lightC->setColor(glm::vec3(1.0f, 1.0f, 1.0f));
lightA->setDirection(glm::normalize(glm::vec3(0.0, -0.8, -0.2)));
lightB->setDirection(glm::normalize(glm::vec3(1.0, -.2, 0.0f)));
lightC->setDirection(glm::normalize(glm::vec3(0.0, 1.0, 0.0)));
//application->scene.addObject(&application->sunlight);
application->scene.getLayer(0)->addObject(lightA);
application->scene.getLayer(0)->addObject(lightB);
application->scene.getLayer(0)->addObject(lightC);
application->scene.getLayer(0)->addObject(&application->camera);
application->defaultLayer->addObject(&application->camera);
// Load compositor
RenderQueue renderQueue;
const std::list<SceneObject*>* objects = application->scene.getLayer(0)->getObjects();
const std::list<SceneObject*>* objects = application->defaultLayer->getObjects();
for (const SceneObject* object: *objects)
renderQueue.queue(object);
RenderContext renderContext;
renderContext.camera = nullptr;
renderContext.layer = application->scene.getLayer(0);
renderContext.layer = application->defaultLayer;
renderContext.queue = &renderQueue;
application->defaultCompositor.load(&renderContext);
// Setup fade-in
application->blackoutImage->setVisible(true);
application->fadeInTween->start();
application->inputManager->addWindowObserver(this);
application->mouse->addMouseButtonObserver(this);
windowResized(application->width, application->height);
// Setup camera controller
application->surfaceCam->setCamera(&application->camera);
application->surfaceCam->setFocalPoint(Vector3(0.0f));
application->surfaceCam->setFocalDistance(300.0f);
application->surfaceCam->setElevation(glm::radians(35.0f));
application->surfaceCam->setAzimuth(glm::radians(-45.0f));
application->surfaceCam->setFocalDistance(50.0f);
application->surfaceCam->setElevation(glm::radians(0.0f));
application->surfaceCam->setAzimuth(glm::radians(0.0f));
application->surfaceCam->setTargetFocalPoint(application->surfaceCam->getFocalPoint());
application->surfaceCam->setTargetFocalDistance(application->surfaceCam->getFocalDistance());
application->surfaceCam->setTargetElevation(application->surfaceCam->getElevation());
application->surfaceCam->setTargetAzimuth(application->surfaceCam->getAzimuth());
application->surfaceCam->update(0.0f);
// Setup arcball
dragging = false;
wasDragging = dragging;
application->arcball.setCenter(Vector2(application->width * 0.5f, application->height * 0.5f));
application->arcball.setRadius(application->height * 0.5f);
// Setup colony
colony.setAntModel(application->antModel);
for (int i = 0; i < 50; ++i)
{
Navmesh::Triangle* triangle = (*navmesh->getTriangles())[0];
ant = colony.spawn(navmesh, triangle, normalize_barycentric(Vector3(0.5f)));
Vector3 forward = glm::normalize(triangle->edge->vertex->position - triangle->edge->next->vertex->position);
Vector3 up = triangle->normal;
ant->setOrientation(forward, up);
application->scene.getLayer(0)->addObject(ant->getModelInstance());
ant->setState(Ant::State::WANDER);
}
ant->setState(Ant::State::IDLE);
// Setup fade-in
application->blackoutImage->setVisible(true);
application->fadeInTween->start();
// Start timer
stateTime = 0.0f;
application->frameTimer.reset();
application->frameTimer.start();
substate = 0;
}
void TitleState::execute()
{
// Calculate delta time (in seconds)
float dt = static_cast<float>(application->frameTimer.microseconds().count()) / 1000000.0f;
application->frameTimer.reset();
// Add dt to state time
stateTime += dt;
stateTime += application->dt;
if (substate == 0 || substate == 1)
{
@ -252,217 +198,43 @@ void TitleState::execute()
{
// Remove fade-in
substate = 1;
application->fadeInTween->stop();
application->blackoutImage->setTintColor(Vector4(0.0f));
application->blackoutImage->setVisible(false);
application->titleFadeInTween->stop();
application->titleImage->setVisible(true);
application->titleImage->setTintColor(Vector4(1.0f));
application->anyKeyFadeInTween->start();
application->anyKeyLabel->setVisible(true);
}
else if (substate == 1)
{
// Enter main menu
substate = 2;
application->titleFadeInTween->stop();
application->titleFadeOutTween->start();
application->anyKeyFadeInTween->stop();
application->anyKeyFadeOutTween->stop();
application->anyKeyLabel->setVisible(false);
application->enterMenu(0);
application->antHillZoomInTween->start();
application->menuSelectorLabel->setVisible(true);
//enterMenu(application, &mainMenu);
application->blackoutImage->setVisible(true);
application->antHillFadeOutTween->start();
}
}
}
}
// Update menu controls
application->menuControlProfile->update();
application->gameControlProfile->update();
// Update input
application->inputManager->update();
// Check state time
if (!fadeIn && stateTime >= blankDuration)
{
// Begin fade-in
fadeIn = true;
}
/*
glm::ivec2 mousePosition = application->mouse->getCurrentPosition();
mousePosition.y = application->height - mousePosition.y;
if (dragging && !wasDragging)
{
dragStart = application->arcball.project(Vector2(mousePosition.x, mousePosition.y));
dragStartRotation = application->displayModelInstance->getTransform().rotation;
}
else if (dragging && wasDragging)
{
Vector3 dragEnd = application->arcball.project(Vector2(mousePosition.x, mousePosition.y));
Quaternion rotation = glm::normalize(glm::rotation(dragStart, dragEnd));
// Update display model
Transform transform = application->displayModelInstance->getTransform();
transform.rotation = glm::normalize(rotation * dragStartRotation);
application->displayModelInstance->setTransform(transform);
}
wasDragging = dragging;
*/
// Check if application was closed
if (application->inputManager->wasClosed() || application->escape.isTriggered())
{
application->close(EXIT_SUCCESS);
return;
}
// Check if fullscreen was toggled
if (application->toggleFullscreen.isTriggered() && !application->toggleFullscreen.wasTriggered())
{
application->changeFullscreen();
}
float rotationSpeed = glm::radians(3.0f) * dt / (1.0f / 60.0f);
if (application->cameraRotateCW.isTriggered())
application->surfaceCam->rotate(-rotationSpeed);
if (application->cameraRotateCCW.isTriggered())
application->surfaceCam->rotate(rotationSpeed);
// Move camera
Vector2 movementVector(0.0f);
if (application->cameraMoveLeft.isTriggered())
movementVector.x -= application->cameraMoveLeft.getCurrentValue();
if (application->cameraMoveRight.isTriggered())
movementVector.x += application->cameraMoveRight.getCurrentValue();
if (application->cameraMoveForward.isTriggered())
movementVector.y -= application->cameraMoveForward.getCurrentValue();
if (application->cameraMoveBack.isTriggered())
movementVector.y += application->cameraMoveBack.getCurrentValue();
if (movementVector.x != 0.0f || movementVector.y != 0.0f)
{
movementVector *= 0.005f * application->surfaceCam->getFocalDistance() * dt / (1.0f / 60.0f);
application->surfaceCam->move(movementVector);
}
// Zoom camera
float zoomFactor = application->surfaceCam->getFocalDistance() / 5.0f * dt / (1.0f / 60.0f);
if (application->cameraZoomIn.isTriggered())
application->surfaceCam->zoom(zoomFactor * application->cameraZoomIn.getCurrentValue());
if (application->cameraZoomOut.isTriggered())
application->surfaceCam->zoom(-zoomFactor * application->cameraZoomOut.getCurrentValue());
float minFocalDistance = 2.0f;
float maxFocalDistance = 500.0f;
application->surfaceCam->setTargetFocalDistance(std::min(std::max(application->surfaceCam->getTargetFocalDistance(), minFocalDistance), maxFocalDistance));
application->surfaceCam->update(dt);
// Navigate menu
if (application->menuDown.isTriggered() && !application->menuDown.wasTriggered())
{
if (application->selectedMenuItemIndex < application->currentMenu->getItemCount() - 1)
{
application->selectMenuItem(application->selectedMenuItemIndex + 1);
}
else
{
application->selectMenuItem(0);
}
}
else if (application->menuUp.isTriggered() && !application->menuUp.wasTriggered())
{
if (application->selectedMenuItemIndex > 0)
{
application->selectMenuItem(application->selectedMenuItemIndex - 1);
}
else
{
application->selectMenuItem(application->currentMenu->getItemCount() - 1);
}
}
if (application->menuSelect.isTriggered() && !application->menuSelect.wasTriggered())
{
application->activateMenuItem(application->selectedMenuItemIndex);
}
else if (application->menuCancel.isTriggered() && !application->menuCancel.wasTriggered())
{
}
float lineHeight = application->menuFont->getMetrics().getHeight();
const UIContainer* container = application->menuContainers[application->currentMenuIndex];
application->menuSelectorLabel->setTranslation(
Vector2(container->getPosition().x - application->menuSelectorLabel->getDimensions().x * 1.5f,
container->getPosition().y + lineHeight * 0.5f - application->menuSelectorLabel->getDimensions().y * 0.5f + lineHeight * application->selectedMenuItemIndex));
float walkSpeed = 3.0f * dt;
float turnSpeed = 4.0f * dt;
Vector3 antVelocity = ant->getForward() * walkSpeed;
if (application->walkForward.isTriggered())
{
ant->move(antVelocity);
}
if (application->walkBack.isTriggered())
{
ant->move(-antVelocity);
}
if (application->turnLeft.isTriggered())
{
ant->turn(turnSpeed);
}
if (application->turnRight.isTriggered())
{
ant->turn(-turnSpeed);
}
colony.update(dt);
// Perform tweening
application->tweener->update(dt);
// Update UI
application->uiRootElement->update();
// Clear to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Render BG
application->renderer.render(application->bgScene);
// Render scene
application->renderer.render(application->scene);
// Form billboard batch for UI then render UI scene
application->uiBatcher->batch(application->uiBatch, application->uiRootElement);
application->renderer.render(application->uiScene);
// Swap buffers
SDL_GL_SwapWindow(application->window);
application->surfaceCam->update(application->dt);
}
void TitleState::exit()
{
std::cout << "Exiting TitleState..." << std::endl;
// Remove objects from scene
application->defaultLayer->removeObject(&application->antHillModelInstance);
application->inputManager->removeWindowObserver(this);
application->exitMenu(application->currentMenuIndex);
application->menuSelectorLabel->setVisible(false);
application->scene.removeLayers();
}
void TitleState::windowClosed()
@ -500,13 +272,3 @@ void TitleState::windowResized(int width, int height)
0.1f,
1000.0f);
}
void TitleState::mouseButtonPressed(int button, int x, int y)
{
dragging = true;
}
void TitleState::mouseButtonReleased(int button, int x, int y)
{
dragging = false;
}

+ 1
- 7
src/states/title-state.hpp View File

@ -33,7 +33,7 @@ using namespace Emergent;
/**
* Displays the title screen.
*/
class TitleState: public ApplicationState, public WindowObserver, public MouseButtonObserver
class TitleState: public ApplicationState, public WindowObserver
{
public:
TitleState(Application* application);
@ -45,17 +45,11 @@ public:
virtual void windowClosed();
virtual void windowResized(int width, int height);
virtual void mouseButtonPressed(int button, int x, int y);
virtual void mouseButtonReleased(int button, int x, int y);
private:
float stateTime;
bool fadeIn;
bool fadeOut;
bool dragging;
bool wasDragging;
Vector3 dragStart;
Quaternion dragStartRotation;
int substate;

Loading…
Cancel
Save