202 lines
5.6 KiB
C++
202 lines
5.6 KiB
C++
#include <cmath>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include <SFML/Graphics.hpp>
|
|
#include <SFML/System.hpp>
|
|
#include <SFML/Window.hpp>
|
|
|
|
#include "main.hpp"
|
|
#include "background.hpp"
|
|
#include "game.hpp"
|
|
#include "mainmenu.hpp"
|
|
|
|
namespace Proto4 {
|
|
|
|
// because we want to create the objects in init(), we use the default
|
|
// constructor, so nothing can go wrong here
|
|
sf::RenderWindow window{};
|
|
AppState state = AppState::MainMenu;
|
|
MainMenu menu{};
|
|
Game game{};
|
|
Background background{};
|
|
sf::Texture bg0, bg1;
|
|
sf::Font font;
|
|
|
|
static bool isFullscreen = false;
|
|
|
|
bool openWindow(bool fullscreen) {
|
|
// set antialising for shapes
|
|
// this doesn't affect textures (requires sf::Texture::setSmooth())
|
|
sf::ContextSettings settings;
|
|
settings.antialiasingLevel = 4;
|
|
|
|
if (fullscreen) {
|
|
//go fullscreen
|
|
sf::VideoMode fsMode = sf::VideoMode::getFullscreenModes()[0];
|
|
window.create(fsMode, gameTitle, sf::Style::Fullscreen, settings);
|
|
isFullscreen = true;
|
|
} else {
|
|
window.create(sf::VideoMode(xResolution, yResolution, colorDepth),
|
|
gameTitle, sf::Style::Default, settings);
|
|
window.setPosition(sf::Vector2i(0, 0));
|
|
isFullscreen = false;
|
|
}
|
|
|
|
window.setMouseCursorVisible(false);
|
|
|
|
if (!window.isOpen()) {
|
|
std::cout << "Unable to open window object. Aborting execution.";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool init() {
|
|
|
|
if (!font.loadFromFile("Audiowide-Regular.ttf")) {
|
|
std::cout << "Unable to load font. Aborting execution.";
|
|
return false;
|
|
}
|
|
|
|
if (!bg0.loadFromFile("img/bg_grid_48.png") ||
|
|
!bg1.loadFromFile("img/bg_grid_72.png")) {
|
|
std::cout
|
|
<< "Unable to load background images. Aborting execution.";
|
|
return false;
|
|
}
|
|
|
|
background.init(bg0, bg1, game.getMainView());
|
|
|
|
if (!menu.init(font) || !game.init()) {
|
|
return false;
|
|
}
|
|
|
|
// set antialising for shapes
|
|
// this doesnt affect textures (requires sf::Texture::setSmooth())
|
|
sf::ContextSettings settings;
|
|
settings.antialiasingLevel = 4;
|
|
|
|
// open window after everything has loaded to avoid
|
|
// 'window not responding' warning
|
|
if (!openWindow(isFullscreen)) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void update(sf::Time timestep, sf::Time currentTime) {
|
|
|
|
// poll for events and pass them to components
|
|
sf::Event event;
|
|
while (window.pollEvent(event)) {
|
|
switch (event.type) {
|
|
case sf::Event::LostFocus:
|
|
game.pause();
|
|
break;
|
|
|
|
case sf::Event::GainedFocus:
|
|
game.resume();
|
|
break;
|
|
|
|
case sf::Event::Resized:
|
|
background.resize(event);
|
|
menu.resize(event);
|
|
game.resize(event);
|
|
break;
|
|
|
|
case sf::Event::KeyPressed:
|
|
// toggle fullscreen
|
|
if (
|
|
event.key.code == sf::Keyboard::F11 ||
|
|
(event.key.code == sf::Keyboard::Return && event.key.alt)
|
|
) openWindow(!isFullscreen);
|
|
|
|
switch (state) {
|
|
case AppState::MainMenu:
|
|
state = menu.handleKey(event);
|
|
break;
|
|
case AppState::Game:
|
|
state = game.handleKey(event);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Update everything that gets updated without events...
|
|
sf::View &gameView = game.getMainView();
|
|
switch (state) {
|
|
case AppState::MainMenu:
|
|
// move camera for background movement
|
|
gameView.setCenter(sf::Vector2f(
|
|
gameView.getCenter().x + timestep.asSeconds() * 100 * std::sin(currentTime.asSeconds()),
|
|
gameView.getCenter().y + timestep.asSeconds() * 100));
|
|
break;
|
|
case AppState::Game:
|
|
state = game.update(window, timestep);
|
|
break;
|
|
case AppState::Exit:
|
|
window.close();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
background.update(gameView, window);
|
|
}
|
|
|
|
void draw() {
|
|
|
|
window.clear(sf::Color::Black);
|
|
window.draw(background);
|
|
|
|
switch (state) {
|
|
case AppState::Game:
|
|
window.draw(game);
|
|
break;
|
|
|
|
case AppState::MainMenu:
|
|
window.draw(menu);
|
|
break;
|
|
|
|
case AppState::Exit:
|
|
break;
|
|
}
|
|
|
|
window.display();
|
|
}
|
|
|
|
void mainloop() {
|
|
|
|
// draw as often as possible and
|
|
// update multiple times with a fixed timestep as needed
|
|
sf::Clock clock;
|
|
sf::Time previousTime = sf::milliseconds(0);
|
|
sf::Time lagTime = sf::milliseconds(0);
|
|
|
|
while (window.isOpen()) {
|
|
sf::Time currentTime = clock.getElapsedTime();
|
|
sf::Time elapsedTime = currentTime - previousTime;
|
|
previousTime = currentTime;
|
|
lagTime += elapsedTime;
|
|
|
|
while (lagTime >= updateTimestep) {
|
|
update(updateTimestep, clock.getElapsedTime());
|
|
lagTime -= updateTimestep;
|
|
}
|
|
draw();
|
|
}
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
if (!Proto4::init())
|
|
return 1;
|
|
Proto4::mainloop();
|
|
return 0;
|
|
}
|