我在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());
在那之后,我对所有现有控件设置源为空:
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()]));
}
当我加载新房间,取消旧房间的所有对象。我还对声音,视频甚至是网格使用了相同的方法 - 它们的源只在它们处于活动状态时加载,并且在它们不再使用时更改为空。
我这样做是为了避免将所有图像和声音存储在RAM中。
问题是,尽管如此,对于这种复杂程度的游戏,游戏仍然消耗大量的内存。
标准的内存使用量大约是700M - 我觉得它太多了。
我怀疑,控件的字典和列表,而不是字符串,消耗所有的内存。
例如,我想这一个使每个网格的副本:
Dictionary<string, Grid> ResGrids = new Dictionary<string, Grid>();
我的问题:
1)是否有使用我现在使用的方法的方式:存储所有控制来源,取消它们,只加载那些需要的,但改进它? 2)有没有办法在文件中存储这样的信息,为每个字典或列表创建文件,然后从中加载正在使用的控件的数据。 3)有没有更好的方法来减少内存使用量,而不会做出太大的改变?
谢谢你在前进, 叶甫盖尼
环顾四周,我认为问题是你[需要冻结'BitmapImage's](https: //stackoverflow.com/a/802394/1270789),否则你每次都加载一个位图的新副本,看起来好像。或者,只能创建一次'BitmapImage'。 –
“我怀疑,”这可能是你的第一个问题 - 你不应该怀疑,在尝试改进某些东西之前你应该知道。 Visual Studio为您提供了很好的工具,以诊断工具的形式实际衡量您的应用性能,包括内存使用情况。如果存在快照,拍摄快照很可能会为您提供足够有用的信息来识别您的问题。 – Milster