我正在制作的游戏消耗太多内存

时间:2017-08-30 06:35:49

标签: c# wpf memory

我在C#上制作游戏。问题是,它使用大量的RAM,用于这种类型和质量的游戏。

我会尽量给出简短但足够好的描述。当然,我不会给出完整的代码,但试着展示我认为相关的内容。

游戏中有一些网格,每个网格代表一个游戏室,每个网格内部都有图像和按钮。图像始终是静态图片。但是有很多图像和按钮。

在我的第一种方法中,我决定将每个图像和声源存储在列表或字典中,这些列表和字典是在游戏开始时创建的,只创建一次。

    Dictionary<string, string> voice_path = new Dictionary<string, string>();
    Dictionary<string, string> video_path = new Dictionary<string, string>();
    Dictionary<string, string> inventory_path = new Dictionary<string, string>();
    Dictionary<string, Image> inventory_convert = new Dictionary<string, Image>();

    Dictionary<string, string> area_path = new Dictionary<string, string>();
    static Dictionary<string, string> CameFrom = new Dictionary<string, string>();
    Dictionary<string, Visibility> ConvertVisibility = new Dictionary<string, Visibility>();
    Dictionary<string, Control> ResObjects = new Dictionary<string, Control>();
    Dictionary<string, Grid> ResGrids = new Dictionary<string, Grid>();
    Dictionary<string, System.Windows.Controls.Image> ResImages = new Dictionary<string, System.Windows.Controls.Image>();
    Dictionary<string, TextBlock> ResTextBlocks = new Dictionary<string, TextBlock>();
    Dictionary<string, Label> ResLabels = new Dictionary<string, Label>();
    Dictionary<string, System.Windows.Controls.Image> to_fill_images_dictionary = new Dictionary<string, System.Windows.Controls.Image>();
    public static Dictionary<string, Action> Merge = new Dictionary<string, Action>();

    List <string> ObjectsVisibility = new List <string>();
    public static List <string> StoryElements = new List <string>();
    static List <string> OpenObjects = new List<string>();
    List<string> to_fill_images_list = new List<string>();

    List<MediaElement> Sounds = new List<MediaElement>();
    List<MediaElement> Musics = new List<MediaElement>();
    List<MediaElement> Voices = new List<MediaElement>();
    List<MediaElement> Videos = new List<MediaElement>();

    List<Image> Images = new List<Image>();

    Dictionary<string, string> image_path = new Dictionary<string, string>();

词典存储图像或按钮,或网格名称及其来自xaml的原始源文件。它们也在开头只加载一次。

        image_path.Add("imgBloodyPodBlood", imgBloodyPodBlood.Source.ToString());
        image_path.Add("imgBloodyPodShardsBlood", imgBloodyPodShardsBlood.Source.ToString());
        image_path.Add("imgComputerConversation", imgComputerConversation.Source.ToString());

之后,我将所有现有控件的source设置为null:

        imgBloodyPodBlood.Source = null;
        imgBloodyPodShardsBlood.Source = null;
        imgComputerConversation.Source = null;

    void ShowAirlock()
    {
        areaAirlock.Background = new ImageBrush(new BitmapImage(new Uri(area_path[areaAirlock.Name.ToString()], UriKind.Relative)));
        imgAirlock_Dark.Source = new BitmapImage(new Uri(image_path[imgAirlock_Dark.Name.ToString()]));
        imgAirlock_Dark_Door.Source = new BitmapImage(new Uri(image_path[imgAirlock_Dark_Door.Name.ToString()]));
        imgAirlock_Dark_Suit.Source = new BitmapImage(new Uri(image_path[imgAirlock_Dark_Suit.Name.ToString()]));
        imgAirlock_Light_Door.Source = new BitmapImage(new Uri(image_path[imgAirlock_Light_Door.Name.ToString()]));
        imgAirlock_Light_Suit.Source = new BitmapImage(new Uri(image_path[imgAirlock_Light_Suit.Name.ToString()]));
        imgAirlockLamp.Source = new BitmapImage(new Uri(image_path[imgAirlockLamp.Name.ToString()]));            
    }

当我加载房间时,它的控件只加载它们:

    void ShowAirlock()
    {
        areaAirlock.Background = new ImageBrush(new BitmapImage(new Uri(area_path[areaAirlock.Name.ToString()], UriKind.Relative)));
        imgAirlock_Dark.Source = new BitmapImage(new Uri(image_path[imgAirlock_Dark.Name.ToString()]));
        imgAirlock_Dark_Door.Source = new BitmapImage(new Uri(image_path[imgAirlock_Dark_Door.Name.ToString()]));
        imgAirlock_Dark_Suit.Source = new BitmapImage(new Uri(image_path[imgAirlock_Dark_Suit.Name.ToString()]));
        imgAirlock_Light_Door.Source = new BitmapImage(new Uri(image_path[imgAirlock_Light_Door.Name.ToString()]));
        imgAirlock_Light_Suit.Source = new BitmapImage(new Uri(image_path[imgAirlock_Light_Suit.Name.ToString()]));
        imgAirlockLamp.Source = new BitmapImage(new Uri(image_path[imgAirlockLamp.Name.ToString()]));            
    }

当我加载新房间时,我取消旧房间的所有对象。我也使用与声音,视频甚至网格相同的方法 - 它们的源仅在它们处于活动状态时加载,并在它们不再使用时更改为null。

我这样做,以避免将所有图像和声音存储在RAM中。

问题是,尽管如此,对于这种复杂程度的游戏,游戏仍会消耗大量内存。

标准内存使用量约为700M - 我发现它太多了。

我怀疑,用于控件而不是字符串的字典和列表会占用所有内存。

例如,我想这个会复制每个网格:

Dictionary<string, Grid> ResGrids = new Dictionary<string, Grid>();

我的问题:

1)有没有办法使用我现在使用的方法:存储所有控件源,使它们无效,只加载所需的那些,但改进它? 2)有没有办法将这样的信息存储在文件中,为每个字典或列表创建文件,然后从中加载正在使用的控件的数据。 3)有没有更好的方法来减少内存使用量,而不会做出太大的改变?

提前谢谢你, 叶甫盖尼

1 个答案:

答案 0 :(得分:0)

运行性能测试(VS中的Alt + F2),然后您就会知道应用程序在哪里消耗RAM。

此外,您没有发布太多代码,因此很难直接帮助您,但保持这么多Dictionaries可能不是一个好主意。转到OOP并为包含所需数据的每个房间创建特定对象。这只是初始化,我们以后不知道你在使用该代码做什么,所以很难提供帮助