public void SetTilesData(SongTileData levelData) { //SongTileData levelData = SaveBinarySongDataSystem.LoadTileDataFromResource(currentLevelData.songData.storeID); if (levelData != null) { if (levelData.songDataModel.version == currentLevelData.songData.version) { listTilesData = levelData.titledata; ticksPerTile = levelData.songDataModel.tickPerTile; this.currentLevelData.BPM = levelData.BPM; this.currentLevelData.denominator = denominator = levelData.denominator; this.currentLevelData.tickPerQuarterNote = levelData.tickPerQuarterNote; } } }
/// <summary> /// Load up the level, and start the game as needed /// </summary> /// <returns></returns> IEnumerator <float> C_StartGame() { ChangeState(UIState.Downloading); //a little time to calm down yield return(Timing.WaitForSeconds(0.1f)); //try to read local song files first SongTileData tileData = SaveBinarySongDataSystem.LoadTileDataFromResource(levelData.songData.storeID); if (tileData == null) { //if there is no local song, download new file from the internet yield return(0); //Debug.Log("Trying to download from the Internet"); levelLoader.DownLoadAndCacheSongData(levelData.songData); } else { //if local song persist, check its version with data from store data if (tileData.songDataModel.version != levelData.songData.version) { //if the version is not alike, download from the internet yield return(0); levelLoader.DownLoadAndCacheSongData(levelData.songData); } else { Resources.UnloadUnusedAssets(); yield return(Timing.WaitForSeconds(0.25f)); //if local version is the latest, load it up and run the game gamelogic.Initialize(); yield return(0); gamelogic.SetLevelData(levelData); yield return(0); gamelogic.SetTilesData(tileData); yield return(0); StartNewGame(); } } }
public void PrepareTileData(Action <float> onProgress = null, Action onComplete = null, Action <string> onError = null) { SongTileData listTileData = SaveBinarySongDataSystem.LoadTileData(currentLevelData.songData.storeID); if (listTileData != null) { if (listTileData.songDataModel.version == currentLevelData.songData.version) { listTilesData = listTileData.titledata; Helpers.Callback(onComplete); } else { CoroutineTitleData(onProgress, onComplete, onError); } } else { CoroutineTitleData(onProgress, onComplete, onError); } }
public static bool SaveTileData(SongTileData saveGame, string name) { //BinaryFormatter formatter = new BinaryFormatter(); //using (FileStream stream = new FileStream(GetSavePath(name), FileMode.Create)) { // try { // formatter.Serialize(stream, saveGame); // } // catch (Exception e) { // Debug.LogWarning(e.Message); // return false; // } //} //return true; //BinaryFormatter formatter = new BinaryFormatter(); string data = JsonUtility.ToJson(saveGame); using (FileStream stream = new FileStream(GetSavePath(name), FileMode.Create)) { try { //binarySerializer.Serialize(saveGame, stream); var bytes = System.Text.ASCIIEncoding.ASCII.GetBytes(data); stream.Write(bytes, 0, bytes.Length); } catch (Exception e) { Debug.LogWarning(e.Message); return(false); } finally { stream.Close(); } } return(true); //return false; }
/// <summary> /// From provided note data, prepare tile data for the game. After this methods is call, the game can be played /// </summary> IEnumerator PrepareTileData(List <NoteData> noteData, List <NoteData> playbackData, float BPM, Action <float> onProgress = null, Action onComplete = null, Action <string> onError = null) { //listNoteData = noteData; listTilesData = new List <TileData>(1000); //we know that note data will always less or equals to playback data //so we will start by traverse through list note data NoteData currentNote, nextNote; int currentNoteIndex; //int loopCount = 0; //int maxLoop = 10; float lastReleaseThreadTime = Time.realtimeSinceStartup; float maxTimeLockThread = 1; //this variable is used to reduce number of cast operation float noteDataCount = noteData.Count; //for each note in view list for (int i = 0; i < noteData.Count; i++) { currentNoteIndex = i; //set up range for checking song data currentNote = noteData[currentNoteIndex]; nextNote = null; //don't hog up all the CPU, save some for rendering task if (lastReleaseThreadTime + maxTimeLockThread >= Time.realtimeSinceStartup) { lastReleaseThreadTime = Time.realtimeSinceStartup; Helpers.CallbackWithValue(onProgress, ((i / noteDataCount))); yield return(null); } //try to get next view note (must be different at timestamp with current note) while (++i < noteData.Count) { //++i; nextNote = noteData[i]; //stop the loop right when next note is found if (nextNote.timeAppear != currentNote.timeAppear) { //decrease i so that at the end of the loop, it can be increased gracefully --i; break; } } if (i >= noteData.Count) { i = noteData.Count - 1; } //how many notes existed at the same timestamp int numConcurrentNotes = i - currentNoteIndex + 1; //print("Num concurrent notes" + numConcurrentNotes + " at " + i); //for each note, create a tile for (int j = currentNoteIndex; j <= i; j++) { //print(string.Format("i {0}, j {1}, Concurrent notes: {2}", i, j, numConcurrentNotes)); //print(string.Format("Current note: {0}, timestamp {1}; Next note; {2}, timestamp: {3}", currentNote.nodeID, currentNote.timeAppear, nextNote.nodeID, nextNote.timeAppear)); //with each note data, there is a tile TileData tileData = new TileData(); tileData.type = TileType.Normal; tileData.notes = new List <NoteData>(); tileData.startTime = currentNote.timeAppear; tileData.startTimeInTicks = currentNote.tickAppear; tileData.soundDelay = 0; //fetch midi data for tile int startTime, endTime; startTime = endTime = -1; switch (numConcurrentNotes) { //only 1 tile case 1: tileData.subType = TileType.Normal; startTime = currentNote.tickAppear; endTime = ((nextNote == null) ? currentNote.tickAppear + currentNote.durationInTick : nextNote.tickAppear); break; //dual tile case 2: tileData.subType = TileType.Dual; if (j % 2 == 0) { startTime = currentNote.tickAppear; endTime = currentNote.tickAppear + (int)(currentNote.durationInTick * 0.5f); } else { tileData.soundDelay = currentNote.duration * 0.5f; startTime = currentNote.tickAppear + (int)(currentNote.durationInTick * 0.5f); endTime = ((nextNote == null) ? currentNote.tickAppear + currentNote.durationInTick : nextNote.tickAppear); } break; //big tile case 3: tileData.subType = TileType.Big; if (listTilesData.Count > 1) { TileData lastTileData = listTilesData[listTilesData.Count - 1]; if (lastTileData.startTimeInTicks != currentNote.tickAppear) { startTime = currentNote.tickAppear; endTime = ((nextNote == null) ? currentNote.tickAppear + currentNote.durationInTick : nextNote.tickAppear); } else { startTime = endTime = -1; } } break; } if (startTime >= 0 && endTime >= 0) { //int _endTimeTmp = i < noteData.Count - 1 ? noteData[i + 1].tickAppear: endTime; AddConcurrentMidiDataByTick( ref tileData, playbackData, startTime, endTime, j ); tileData.durationInTicks = currentNote.durationInTick; tileData.duration = currentNote.duration; //if a tile has duration belong to the normal tile's range if (minTickPerTile <= tileData.durationInTicks && tileData.durationInTicks <= maxTickPerTile) { //set it as so tileData.type = TileType.Normal; listTilesData.Add(tileData); } else { //else, it is either a long note... if (maxTickPerTile < tileData.durationInTicks) { tileData.type = TileType.LongNote; listTilesData.Add(tileData); } else { //... or just an error note, f**k that shit //Debug.LogWarning(string.Format("A tile data has duration of {0}, which is less than a normal tile ({1}), please check. It has Index of {2}, midi note {3}", tileData.durationInTicks, currentLevelData.songData.tickPerTile, currentNoteIndex, currentNote.nodeID)); } } } } } //easy, start render in the next frame SongTileData b_data = new SongTileData(); b_data.titledata = listTilesData; b_data.songDataModel = currentLevelData.songData; SaveBinarySongDataSystem.SaveTileData(b_data, b_data.songDataModel.storeID); yield return(null); Helpers.Callback(onComplete); }