如何高效从资源文件夹获取扑克牌图片?替代手动逐个赋值方案
嘿,我懂你现在的麻烦——手动写每个牌面的switch分支实在太啰嗦了,要是写到King的话,代码得臃肿成什么样啊。咱们用几个小技巧就能把这堆重复代码给干掉,让逻辑清爽多了!
核心优化思路:利用命名规则+映射+动态获取
你的资源命名规则非常规整({Suit}_{Number}),这正好是简化代码的突破口,不用再写一堆if-else和switch分支。
1. 先建立牌面与数字的映射字典
把"Ace"、"Deuce"这些文本牌面转换成对应的数字,这样就能统一拼接资源名称了:
// 定义一个全局的映射字典,一次性写完所有牌面 private static readonly Dictionary<string, int> FaceToNumber = new Dictionary<string, int> { {"Ace", 1}, {"Deuce", 2}, {"Three", 3}, {"Four", 4}, {"Five", 5}, {"Six", 6}, {"Seven", 7}, {"Eight", 8}, {"Nine", 9}, {"Ten", 10}, {"Jack", 11}, {"Queen", 12}, {"King", 13} };
2. 用反射动态获取资源(替代重复的if-else)
因为资源命名是固定格式,我们可以通过反射直接从Properties.Resources里拿到对应的图片,不用逐个写死:
// 先从映射字典里拿到当前牌面的数字 if (!FaceToNumber.TryGetValue(picCard.Face, out int cardNumber)) { // 处理无效牌面的情况,比如抛出提示或者直接返回 return; } // 拼接出资源名称,比如"Hearts_1" string resourceName = $"{picCard.Suit}_{cardNumber}"; // 通过反射获取资源并设置给PictureBox var resourceProperty = typeof(Properties.Resources).GetProperty( resourceName, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public ); if (resourceProperty != null && resourceProperty.PropertyType == typeof(System.Drawing.Image)) { picPlayer[count].Image = (System.Drawing.Image)resourceProperty.GetValue(null); }
3. 简化分数计算逻辑(替代重复的分数累加)
原来每个switch case里都有几乎一样的分数计算,现在可以统一处理:
int scoreValue = cardNumber; // 如果你需要给Ace做特殊处理(比如算1或11),单独加判断就行 if (picCard.Face == "Ace") { scoreValue = 1; // 这里可以根据你的游戏规则调整成11或者让玩家选择 } // 根据count判断是电脑还是玩家加分 if (count <= 1) { computer.Score += scoreValue; } else { player.Score += scoreValue; }
4. 整合后的完整简化代码
把上面的逻辑整合到你的方法里,原来冗长的switch就完全可以删掉了:
private static readonly Dictionary<string, int> FaceToNumber = new Dictionary<string, int> { {"Ace", 1}, {"Deuce", 2}, {"Three", 3}, {"Four", 4}, {"Five", 5}, {"Six", 6}, {"Seven", 7}, {"Eight", 8}, {"Nine", 9}, {"Ten", 10}, {"Jack", 11}, {"Queen", 12}, {"King", 13} }; private void AssignCards(Card picCard, int count) { List<PictureBox> picPlayer = new List<PictureBox>() { picDealer1, picDealer2, picPlayer1, picPlayer2 }; if (clickCount == 1) picPlayer.Add(picPlayer3); if (clickCount == 2) { picPlayer.Add(picPlayer3); picPlayer.Add(picPlayer4); } // 1. 获取牌面对应的数字 if (!FaceToNumber.TryGetValue(picCard.Face, out int cardNumber)) { return; } // 2. 计算并添加分数 int scoreValue = cardNumber; if (picCard.Face == "Ace") { scoreValue = 1; // 按需调整Ace的分数规则 } if (count <= 1) { computer.Score += scoreValue; } else { player.Score += scoreValue; } // 3. 动态设置图片 string resourceName = $"{picCard.Suit}_{cardNumber}"; var resourceProperty = typeof(Properties.Resources).GetProperty( resourceName, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public ); if (resourceProperty != null) { picPlayer[count].Image = (System.Drawing.Image)resourceProperty.GetValue(null); } }
额外性能优化:缓存图片资源
如果担心反射的性能问题,可以在程序启动时把所有卡牌图片提前加载到缓存字典里,之后直接从缓存取:
private static readonly Dictionary<string, Image> CardImageCache = new Dictionary<string, Image>(); // 程序初始化时调用这个方法 private void InitializeCardImages() { string[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"}; foreach (var faceEntry in FaceToNumber) { foreach (var suit in suits) { string resourceName = $"{suit}_{faceEntry.Value}"; var prop = typeof(Properties.Resources).GetProperty( resourceName, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public ); if (prop != null) { CardImageCache[$"{suit}_{faceEntry.Key}"] = (Image)prop.GetValue(null); } } } } // 之后设置图片直接用缓存 picPlayer[count].Image = CardImageCache[$"{picCard.Suit}_{picCard.Face}"];
内容的提问来源于stack exchange,提问作者Labib Zaman
相关产品推荐
相关产品推荐

