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

标签 c# xna loading

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

到目前为止,我能够让游戏通过检测文件路径名是否包含 (".mp3") 来检测文件是否为音乐,但我试图将文件名实际加载到列表中使用 for 循环键入 Song。代码如下所示。

(声明)

List<Song> songsToPlay;
string[] fileNames

(初始化)

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

(加载内容)

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]") 
}

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

最佳答案

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

没有必要回避那个类(class)。 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允许您加载一个目录,以便您可以枚举其中的所有文件。

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

  • *.* - 您正在寻找名为 <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虽然没有赋予变量任何神奇的能力。声明变量后,您将无法分配不同类型的变量。它只是实现完全相同功能的捷径。

关于c# - 如何在不实际使用 Content 类的情况下加载 MP3 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8773033/

相关文章:

java - Checker Framework Eclipse 插件加载时抛出异常

c# - 如何优化获取/设置属性修饰属性的性能?

XNA 3.0 中的 Xna 4.0 项目

c# - 通过 TCP 发送/接收文件

c# - 如何创建用于访问 XNA 内容项目中文件的强类型结构?

serialization - XNA - WP7 - TiledLib - 序列化和逻辑删除

java - 如何加载没有标识符的 Json 属性?

database - 预加载数据的好方法是什么?

c# - RegAsm dll 没有类型注册

c# - WPF:以编程方式引发 SelectionChangedEvent