如何在不实际使用Content类的情况下加载MP3文件?

时间:2012-01-07 20:52:57

标签: c# xna loading

我是使用C Sharp编程的初学者,我使用的是XNA SDK。我正在尝试制作一个简单的游戏,以帮助我的同学们在学校上学,我决定如果有一些方法可以让他们在文件中玩游戏时放置他们想要听的音乐,并且让游戏自动加载音乐文件,并在播放列表中播放。

到目前为止,通过检测文件路径名称是否包含(“。mp3”),我能够让游戏检测文件是否是音乐,但我试图将文件名实际加载到列表中键入Song,使用for循环。代码看起来像这样。

(声明)

List<Song> songsToPlay;
string[] fileNames

(初始化)

fileNames[] = Directory.GetFiles(".\Music")

(LoadContent)

for (int i = 0; i < fileNames.Count(); i++)
{
      if (fileNames[i].Contains(".mp3")
      {
          songsToPlay.Add(fileNames[i]);
      }
}

我一直在尝试找到一种方法将整个文件夹添加到内容目录中,并让它更像

for (int i = 0; i < fileNames.Count(); i++)
{
    songsToPlay.Add(Content.Load<Song>("fileNames[i]") 
}

我一直无法找到某种方法来做到这一点......有谁知道如何使这项工作,或更好的方法来做到这一点?

2 个答案:

答案 0 :(得分:3)

如果您的项目内容中包含文件,则应使用the ContentManager class。它为您提供的不仅仅是文件加载。例如,当您不再使用它时,您可以use Content.Unload to unload all your data

没有必要避免这个课程。 This page has an example显示您正在尝试做的事情:

public static Dictionary<string, T> LoadContent<T>(
    this ContentManager contentManager, string contentFolder)
{
   var dir = new DirectoryInfo(contentManager.RootDirectory
       + "\\" + contentFolder);
   if (!dir.Exists)
      throw new DirectoryNotFoundException();

   var result = new Dictionary<string, T>();

   foreach (FileInfo file in dir.GetFiles("*.mp3"))
   {
      string key = Path.GetFileNameWithoutExtension(file.Name);

      result[key] = contentManager.Load<T>(
          contentManager.RootDirectory + "/" + contentFolder + "/" + key);
   }

   return result;
}

你可以像这样使用它:

var songs = Content.LoadContent<Song>("Songs");

对此代码略有改进......

一旦上述代码正常运行,我建议您稍作修改:

var dir = new DirectoryInfo(
    System.IO.Path.Combine(contentManager.RootDirectory, contentFolder));

如果可以避免,则不应通过字符串连接手动构建路径。我不知道你可以为ContentManager路径做同样的事情,所以你可能不得不坚持使用字符串连接。

编辑:你还没有在课堂上使用过多的构造

由于您尚未在班级中使用extension methodsthe static keyword,并且可能没有使用词典,因此这是一种更简单的方法:

string contentFolder = "Music";
var dir = new DirectoryInfo(Content.RootDirectory + "\\" + contentFolder);

if (!dir.Exists)
{
    // Todo: Display a message to the user instead?
    throw new DirectoryNotFoundException();
}

string[] files = dir.GetFiles("*.mp3");

for (int i = 0; i < files.Count(); ++i)
{
    FileInfo file = files[i];
    string key = System.IO.Path.GetFileNameWithoutExtension(file.Name);

    var song = Content.Load<Song>(
        Content.RootDirectory + "/" + contentFolder + "/" + key);

    songsToPlay.Add(song);
}

Edit2:对第二个代码示例的一些解释

The DirectoryInfo class允许您加载目录,以便枚举其中的所有文件。

DirectoryInfo上的

The GetFiles method允许您使用通配符样式模式匹配来枚举文件。文件的通配符模式匹配意味着在给出这些模式时:

  • *.* - 您正在寻找名为<anything>.<anything>
  • 的文件
  • *.mp3 - 您正在寻找<anything>.mp3

throw表示抛出异常。这将故意停止执行代码并显示良好的错误消息(“找不到目录”)和行号。 There is a lot to learn about exception handling,所以我不会试着在这里描述一下。

GetFileNameWithoutExtension应该是显而易见的,因为它名字很好。

  

Content.RootDirectory + "/" + contentFolder + "/" + key

最后一点代码将构建一个包含内容根目录,歌曲子目录和每个文件名的字符串,使用它可以理解的名称(因为它不知道文件扩展名)

var表示“我分配给它的任何类型”。这是一个捷径。例如,而不是键入:

List<string> someList = new List<string>();

您输入:

var someList = new List<string>();

var必须知道作业右侧的类型。这很有用,因为你可以avoid repeating yourself

使用var并不会赋予变量任何神奇的能力。一旦声明了变量,就无法分配不同类型的变量。它只是完全相同功能的捷径。

答案 1 :(得分:0)

使用Song.FromUri方法:

Song.FromUri("audio name", new Uri(@"C:\audio.mp3"));

文件路径不能包含空格!

请在此处查看解决方法:XNA 4 Song.fromUri containing Spaces