project-kyoku/application.cpp

184 lines
4.0 KiB
C++
Raw Normal View History

2021-04-03 19:14:31 +02:00
#include "application.h"
2021-04-08 18:08:01 +02:00
2021-04-03 19:14:31 +02:00
#include <SFML/Graphics/Color.hpp>
#include <SFML/Window/Event.hpp>
2021-04-04 22:43:12 +02:00
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f);
2021-04-03 19:14:31 +02:00
Application::Application() :
2021-04-05 16:17:57 +02:00
_game_window({1280, 720}, "Test"),
_debug(true)
2021-04-03 19:14:31 +02:00
{
2021-04-08 18:08:01 +02:00
_font.loadFromFile("/usr/share/qtcreator/fonts/SourceCodePro-Regular.ttf");
2021-04-05 16:17:57 +02:00
_grade.setFont(_font);
_grade.setPosition(160, 160);
2021-04-08 21:51:59 +02:00
_grade.setFillColor(sf::Color(255, 0, 0));
2021-04-05 16:17:57 +02:00
_grade.setCharacterSize(35);
2021-04-08 18:08:01 +02:00
_grade.setString("NOT INIT");
2021-04-03 19:14:31 +02:00
}
void Application::run()
{
std::string song_filename = "/home/naiji/METEOR.flac";
2021-04-04 22:43:12 +02:00
_music.openFromFile(song_filename);
2021-04-05 16:17:57 +02:00
_music.play();
2021-04-08 18:08:01 +02:00
_music.setVolume(2);
2021-04-05 16:17:57 +02:00
_game_window.display();
startGameLoop();
}
static bool isOneFramePassed(const sf::Time& time_since_last_update)
{
return time_since_last_update >= TIME_PER_FRAME;
}
void Application::startGameLoop()
{
2021-04-04 22:43:12 +02:00
sf::Clock timer;
sf::Time time_since_last_update = sf::Time::Zero;
2021-04-05 16:17:57 +02:00
while (_game_window.isOpen())
{
input();
2021-04-03 19:14:31 +02:00
2021-04-04 22:43:12 +02:00
time_since_last_update += timer.restart();
2021-04-05 16:17:57 +02:00
if (isOneFramePassed(time_since_last_update))
2021-04-04 22:43:12 +02:00
{
time_since_last_update -= TIME_PER_FRAME;
update();
draw();
}
2021-04-03 19:14:31 +02:00
}
}
2021-04-08 21:51:59 +02:00
static void makeGradeString(const NoteGrade::Rating& rating, sf::Text& text)
2021-04-03 19:14:31 +02:00
{
2021-04-05 16:17:57 +02:00
switch (rating)
2021-04-03 19:14:31 +02:00
{
2021-04-05 16:17:57 +02:00
case (NoteGrade::Rating::BAD):
2021-04-08 21:51:59 +02:00
text.setString("BAD");
text.setFillColor(sf::Color(255, 255, 255, 255));
2021-04-05 16:17:57 +02:00
break;
case (NoteGrade::Rating::GREAT):
2021-04-08 21:51:59 +02:00
text.setString("GREAT");
text.setFillColor(sf::Color(255, 255, 0, 255));
2021-04-05 16:17:57 +02:00
break;
case (NoteGrade::Rating::WRONG):
2021-04-08 21:51:59 +02:00
text.setString("WRONG");
text.setFillColor(sf::Color(120, 120, 120, 255));
2021-04-05 16:17:57 +02:00
break;
case (NoteGrade::Rating::GOOD):
2021-04-08 21:51:59 +02:00
text.setString("GOOD");
text.setFillColor(sf::Color(255, 100, 120, 255));
2021-04-05 16:17:57 +02:00
break;
2021-04-03 19:14:31 +02:00
}
2021-04-05 16:17:57 +02:00
}
2021-04-04 22:43:12 +02:00
2021-04-05 16:17:57 +02:00
void Application::input()
{
sf::Event event;
while (_game_window.pollEvent(event))
2021-04-03 19:14:31 +02:00
{
2021-04-05 16:17:57 +02:00
switch (event.type)
{
default:
break;
case (sf::Event::Closed):
_game_window.close();
break;
case (sf::Event::KeyPressed):
onKeyPressed(event.key.code);
break;
}
2021-04-04 22:43:12 +02:00
}
2021-04-05 16:17:57 +02:00
}
2021-04-04 22:43:12 +02:00
2021-04-05 16:17:57 +02:00
static Note::Arrow keyToArrow(const sf::Keyboard::Key &key)
{
switch (key)
2021-04-04 22:43:12 +02:00
{
2021-04-05 16:17:57 +02:00
case sf::Keyboard::A:
case sf::Keyboard::Left:
case sf::Keyboard::Num4:
return Note::Arrow::LEFT;
case sf::Keyboard::W:
case sf::Keyboard::Up:
case sf::Keyboard::Num8:
return Note::Arrow::UP;
case sf::Keyboard::D:
case sf::Keyboard::Right:
case sf::Keyboard::Num6:
return Note::Arrow::RIGHT;
case sf::Keyboard::S:
case sf::Keyboard::Down:
case sf::Keyboard::Num2:
return Note::Arrow::DOWN;
default:
return Note::Arrow::NONE;
2021-04-04 22:43:12 +02:00
}
2021-04-05 16:17:57 +02:00
}
void Application::onKeyPressed(const sf::Keyboard::Key &key)
{
if (key == sf::Keyboard::D)
{
_debug.toggle();
return;
}
2021-04-08 18:08:01 +02:00
onTap(keyToArrow(key));
}
2021-04-05 16:17:57 +02:00
2021-04-08 18:08:01 +02:00
void Application::onTap(const Note::Arrow &arrow)
{
if (arrow == Note::Arrow::NONE)
return;
const auto music_offset = _music.getPlayingOffset().asMicroseconds();
const auto note = _timeline.fetchActiveNote(music_offset);
if (note)
{
const auto tap_result = note->onTap(arrow, music_offset);
2021-04-08 21:51:59 +02:00
makeGradeString(tap_result.rating, _grade);
_grade.setFillColor(sf::Color(255, 255, 255, 255));
2021-04-05 16:17:57 +02:00
}
}
void Application::update()
{
const auto music_offset = _music.getPlayingOffset().asMicroseconds();
_timeline.update(music_offset);
_debug.update(music_offset);
2021-04-04 22:43:12 +02:00
if (_grade.getFillColor().a > 0) // TODO: Encapsulate
2021-04-04 22:43:12 +02:00
{
2021-04-05 16:17:57 +02:00
const auto alpha = _grade.getFillColor().a - 20;
_grade.setFillColor(sf::Color(255, 255, 255, alpha < 0 ? 0 : alpha));
2021-04-03 19:14:31 +02:00
}
}
void Application::draw()
{
2021-04-05 16:17:57 +02:00
_game_window.clear();
_game_window.draw(_timeline);
_game_window.draw(_debug);
2021-04-05 16:17:57 +02:00
_game_window.draw(_grade);
_game_window.display();
2021-04-03 19:14:31 +02:00
}