[add] Added Song and Implemented loading a list of songs.

This commit is contained in:
falsycat 2019-10-13 00:00:00 +00:00
parent 78c18de0f8
commit 1a289a6dda
5 changed files with 142 additions and 7 deletions

1
.bin/.gitignore vendored
View File

@ -1,3 +1,4 @@
*
!/.gitignore
!/fonts
!/songs

15
.bin/songs/list.json Normal file
View File

@ -0,0 +1,15 @@
[
{
"name": "test-60bpm",
"bpm": 60,
"music": "test-60bpm.ogg",
"script": "test-60bpm.sj",
"preview": {
"play-offset": 1000,
"play-loop": 2000,
"bg-inner-color": [0.8, 0.8, 0.8, 1],
"bg-outer-color": [0.8, 0.8, 0.8, 1]
}
}
]

View File

@ -1,11 +1,17 @@
/// License: MIT
module sj.Game;
import std.algorithm,
std.file,
std.json,
std.path;
import sj.AbstractGame,
sj.FontSet,
sj.LobbyWorld,
sj.ProgramSet,
sj.SelectScene,
sj.Song,
sj.TitleScene;
///
@ -13,13 +19,19 @@ class Game : AbstractGame {
public:
///
this() {
const path = thisExePath.dirName;
const songs_dir = buildPath(path, "songs");
const songs_list = buildPath(songs_dir, "list.json").readText;
songs_ = Song.CreateFromJson(songs_list.parseJSON, songs_dir);
programs_ = new ProgramSet;
fonts_ = new FontSet;
lobby_ = new LobbyWorld(programs_);
title_ = new TitleScene(lobby_, programs_);
select_ = new SelectScene(lobby_, programs_);
select_ = new SelectScene(lobby_, programs_, songs_);
title_.SetupSceneDependency(select_);
select_.SetupSceneDependency(title_);
@ -35,9 +47,13 @@ class Game : AbstractGame {
programs_.destroy();
fonts_.destroy();
songs_.each!destroy();
}
private:
Song[] songs_;
ProgramSet programs_;
FontSet fonts_;

View File

@ -12,6 +12,7 @@ import sj.KeyInput,
sj.LobbyWorld,
sj.ProgramSet,
sj.SceneInterface,
sj.Song,
sj.TitleScene,
sj.util.Animation,
sj.util.Easing,
@ -22,8 +23,9 @@ class SelectScene : SceneInterface {
public:
///
this(LobbyWorld lobby, ProgramSet program) {
this(LobbyWorld lobby, ProgramSet program, Song[] songs) {
lobby_ = lobby;
songs_ = songs.dup;
sound_ = sfSound_create();
soundres_.Load();
@ -80,12 +82,12 @@ class SelectScene : SceneInterface {
LobbyWorld lobby_;
sfSound* sound_;
Song[] songs_;
sfSound* sound_;
SoundResources soundres_;
FirstSetupState first_state_;
FirstSetupState first_state_;
AbstractSceneState status_;
}
@ -145,7 +147,7 @@ private class FirstSetupState : AbstractSceneState {
owner.lobby_.background.outer_color = bg_outer_ease_.Calculate(ratio);
if (anime_.isFinished) {
stage_appear_state_.Initialize();
stage_appear_state_.Initialize(0);
return CreateResult(stage_appear_state_);
}
return CreateResult(this);
@ -170,8 +172,11 @@ private class StageAppearState : AbstractSceneState {
enum AnimeFrames = 30;
enum CubeRotationSpeed = vec3(0, PI/500, 0);
void Initialize() { // TODO: pass a stage data
void Initialize(size_t song_index) {
song_index_ = song_index;
anime_ = Animation(AnimeFrames);
cube_interval_ease_ = Easing!float(owner.lobby_.cube_interval, 0.005);
sfSound_setBuffer(owner.sound_, owner.soundres_.spotlight);
@ -187,6 +192,8 @@ private class StageAppearState : AbstractSceneState {
}
private:
size_t song_index_;
Animation anime_;
Easing!float cube_interval_ease_;

96
src/sj/Song.d Normal file
View File

@ -0,0 +1,96 @@
/// License: MIT
module sj.Song;
import std.array,
std.conv,
std.exception,
std.json,
std.path,
std.string,
std.typecons;
import derelict.sfml2.audio,
derelict.sfml2.system;
import gl4d;
static import sjplayer;
///
class Song {
public:
///
static struct PreviewConfig {
public:
///
size_t play_offset;
///
Nullable!vec4 bg_inner_color;
///
Nullable!vec4 bg_outer_color;
}
///
static Song[] CreateFromJson(in JSONValue json, string basepath) {
auto result = appender!(Song[]);
result.reserve(json.array.length);
foreach (item; json.array) {
result ~= new Song(item, basepath);
}
return result[];
}
///
this(in JSONValue json, string basepath) {
const music_path = buildPath(basepath, json["music"].str);
name_ = json["name"].str;
bpm_ = GetNumericAsFloatFromJson(json["bpm"]);
music_ = sfMusic_createFromFile(music_path.toStringz).enforce;
script_path_ = buildPath(basepath, json["script"].str);
// TODO: update preview config
}
~this() {
sfMusic_destroy(music_);
}
///
void PlayForGame() {
sfMusic_setPlayingOffset(music_, sfMilliseconds(0));
sfMusic_play(music_);
}
///
void PlayForPreview() {
sfMusic_setPlayingOffset(
music_, sfMilliseconds(preview_.play_offset.to!int));
sfMusic_play(music_);
}
///
sjplayer.Context CreatePlayerContext() const {
assert(false); // TODO:
}
///
@property ref const(PreviewConfig) preview() const {
return preview_;
}
private:
static float GetNumericAsFloatFromJson(in JSONValue json) {
return json.type == JSONType.float_? json.floating: json.integer;
}
string name_;
float bpm_;
sfMusic* music_;
string script_path_;
PreviewConfig preview_;
}