我正在考虑在XNA 3.1中创建一个处理阴影绘制的类。我知道有很多方法可以做到这一点,但是我想要做一些像应该有阴影的所有对象的List并将List传递给shadow类,以便迭代每个对象并绘制阴影。< / p>
我想这样做的原因是因为我可以用布尔值轻松控制阴影是否存在。
所有类型的List可能不太可能,我的备份是Object类型的List但是我不知道如何将List中的Object类型的元素转换回它们各自的类型,以便我可以访问它们的属性
我的第二个备份是使所有具有阴影的对象派生自一个名为ShadowObject的类或其他东西,并制作该类型的List。这是一个非常简单的解决方案,但我之所以没有这样做的原因是因为我不喜欢虚拟课的想法只是为了使某些东西有用,但也许我应该开始喜欢它。
我的最后一个备份是进入每个会有阴影的类,并有一个布尔值来查看是否应该绘制阴影并处理类本身中的绘图,我认为这不应该被认为是一个选项,如果我想改变影子力学,我必须在每个班级改变它。
所以我想所有类型的列表都是我公开的官方问题,但我愿意接受我的备份计划的答案,建议和批评。
编辑:我知道接口,但我对xixonia的回答的评论是对xixonia的回答,在阅读了更多接口之后,我认为拥有一个ShadowCaster类会更合适。它可以处理所有阴影绘图,因为所有阴影都以相同的方式绘制,我不需要为每个对象单独定义它,就像接口需要我一样。
答案 0 :(得分:2)
而不是“虚拟类”ShadowObject为什么不创建一个接口IShadowObject,它将公开所有必要的方法并使用:
List<IShadowObject>
答案 1 :(得分:2)
我相信您应该使用界面,并确保所有“DrawShadow”方法都与该界面匹配。这样,您就可以创建与界面匹配的阴影连接器列表。
只要对象实现了该接口,您就知道可以告诉它绘制阴影。如果使用正确的绘图设备,阴影的实际绘制将留给对象本身。
例如:
class Program
{
public static void Main()
{
var shadowCasters = new List<ICastShadow>();
shadowCasters.Add(new Car());
shadowCasters.Add(new Plane());
var castShadows = true;
if (castShadows)
{
foreach (var caster in shadowCasters)
{
caster.DrawShadow(null);
}
}
Console.Read();
}
public class Car : ICastShadow
{
public void DrawShadow(object device)
{
Console.WriteLine("Car Shadow!");
}
}
public class Plane : ICastShadow
{
public void DrawShadow(object device)
{
Console.WriteLine("Plane Shadow!");
}
}
public interface IShadowCaster
{
void DrawShadow(object device);
}
}
当您需要测试您的对象是否能够投射阴影时,您可以使用“是”关键字...
if(myTrain is ICastShadow)
{
shadowCasters.Add(myTrain);
}
希望这有帮助! :)
修改强>:
你不想使用继承的原因是你的游戏对象都以不同的方式绘制阴影,如果你的某些派生类没有投射阴影。例如:
你有一个BrickBuilding和一个GlassBuilding。砖建筑应该投下阴影,玻璃建筑不应该。它们都继承自Building,它继承自ShadowCaster。即使所有阴影投射类都以相同的方式绘制阴影,您仍然需要将ShadowCaster的方法设置为虚拟,因此GlassBuilding可以覆盖它们,并且在调用该方法时不执行任何操作。
使用合成而不是继承(例如:使用接口),您可以在上仅构建实际投射阴影的类的阴影绘制方法,并且您的类中只有一个类层次结构(这使得可维护性变得轻而易举)。
那么当你使用一个界面并且你开始反复重复相同的逻辑时会发生什么,因为你的阴影绘图类都以相同的方式绘制阴影?显然这不是最好的主意。但如果它们都以相同的方式绘制阴影,则可以使用另一个类为绘制阴影。然后是“ShadowCaster”课程。
然后,每个对象上的阴影绘图实现将调用此ShadowCaster上的方法为其绘制阴影。这允许每个对象以不同的方式绘制阴影的选项,但也为每个对象提供了一种使用默认阴影绘图实现的方法。它还提供了一种方法来轻松添加和删除为特定对象绘制阴影的功能(简单的是不要让对象实现ICastShadow接口)。
更进一步,你可以像对待另一种绘图方法一样对待阴影投射,并创建一个用于绘制阴影/粒子/反射/三角发光等的通用界面,并创建不同的“模块”来执行这些不同的操作的东西。不要让你的类实现'ICastShadows',让它实现“IDrawModules”,然后在运行时为每个类提供正确的模块。
换句话说,您可以向BrickBuilding添加“CastShadow”模块,并向GlassBuilding添加“Reflect”模块,并在两个对象(来自IDrawModules界面)上调用代码“DrawModules”。
好的,这真的很长,希望这有帮助,而且不会太混乱。
我建议阅读Head First Design Patterns的前几章。这是一本基于java的书,但大多数语言的原则都是一样的。
答案 2 :(得分:0)
我对游戏开发知之甚少,但看起来像System.Generic.Collection.List得到了XNA框架的支持。那将是你的任何类型的列表。
答案 3 :(得分:0)
您可以使用“is”运算符来检查类型。
public bool check(object obj)
{
return obj is ShadowStuff;
// or obj.GetType() == ShadowStuff
}
施放:
(ShawdowStuff) obj ;