我正在寻找一种方法来加速我的游戏引擎的绘制,这是目前的重要瓶颈,并导致减速.我正处于将其转换为XNA的边缘,但我只是注意到了一些东西.
说我有一个我已加载的小图像.
Image img = Image.FromFile("mypict.png");
Run Code Online (Sandbox Code Playgroud)
我们想要在屏幕上绘制一个图片框.所以我们有一个处理程序.
pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
Run Code Online (Sandbox Code Playgroud)
我希望我们加载的图像在图片框上平铺(毕竟这是一个游戏).为什么这个代码:
void pictureBox1_Paint(object sender, PaintEventArgs e)
{
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x++)
e.Graphics.DrawImage(image, x * 16, y * 16, 16, 16);
}
Run Code Online (Sandbox Code Playgroud)
超过此代码的时间超过25倍:
Image buff = new Bitmap(256, 256, PixelFormat.Format32bppPArgb); // actually a form member
void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = Graphics.FromImage(buff))
{
for (int y = 0; y < 16; y++) …Run Code Online (Sandbox Code Playgroud) 我为自己承担了相当艰巨的挑战.在我的XNA游戏中,我想实现Blargg的NTSC过滤器.这是一个C库,它转换位图使其看起来像是在具有NTSC标准的CRT电视上输出的.真的很准确.
我曾经尝试过的第一件事就是通过将其称为dll来使用C库本身.在这里,我有两个问题,1.我无法正确复制一些数据,因此图像搞砸了,但更重要的是,2.它非常慢.它需要获取XNA Texture2D位图数据,将其传递给过滤器,然后再次将数据设置为纹理.帧率被破坏了,所以我不能沿着这条路走下去.
现在我正在尝试将滤镜转换为像素着色器.这里的问题(如果你喜欢看代码 - 我正在使用SNES,因为它是最简单的)是它处理非常大的数组,并依赖于有趣的指针操作.我已经做了很多工作,重写算法以按像素独立工作,就像像素着色器需要的那样.但我不知道这是否会奏效.我来找你,看看是否有可能完成这项工作.
编辑:#2的附录.我刚读到某个地方不仅hlsl不能通过变量访问数组,而且即使要展开它,索引也必须在编译时计算.这是真的,还是"展开"解决了这个问题?如果这是真的,我想我搞砸了.有什么方法吗?我的算法基本上是一个美化版本的"输入像素是这种颜色,所以在这个巨大的数组中查找我的输出像素值."
我最近在不同的项目中多次遇到过这种情况.这是一个四个表格的图表,标有字母:
A
1 / \ 1
/ \
* / \ *
B C
1 \ / 1
\ /
* \ / *
D
Run Code Online (Sandbox Code Playgroud)
在这种情况下,有可能将数据变得不一致如果从按键B到A,并C以A不匹配给定的D.
对于特定的(组成的)示例,想象A是Company,B是Employee,C是Project和D是WorkItem.在这种情况下,没有什么能阻止创建工作项,声称被分配给一个甚至不为拥有该项目的公司工作的人.
我主要只是好奇,有这个问题的设计解决方案吗?我知道在实际的应用程序中,您可以使用触发器或其他一些安全措施.我还没有找到一种方法来改变表格,使这种不一致变得不可能.有办法吗?
请注意,只是切断了连接中的一个,像C到A不行的,因为如果没有D了存在的C,你就没有追查连接回的方式A.
如果我有一个从几个地方调用的函数,并且它需要满足某些条件来执行它所执行的任何操作,应该在哪里检查该条件?在我的情况下,它是绘图 - 如果按住鼠标按钮,然后执行绘图逻辑(这是在拖动时在鼠标移动处理程序中完成的.)
选项一说将它放在函数中,以确保它被检查.抽象,如果你愿意的话.
public function Foo() {
DoThing();
}
private function DoThing() {
if (!condition) return;
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,当读取Foo可能远离DoThing它的代码时,它看起来像一个bug.第一个想法是没有检查条件.
然后,选项二是在打电话之前检查.
public function Foo() {
if (condition) DoThing();
}
Run Code Online (Sandbox Code Playgroud)
这读起来更好,但现在您不得不担心从您调用它的任何地方进行检查.
选项三是将函数重命名为更具描述性.
public function Foo() {
DoThingOnlyIfCondition();
}
private function DoThingOnlyIfCondition() {
if (!condition) return;
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
这是"正确的"解决方案吗?或者这有点太过分了?我觉得如果一切都像这个函数名称将开始复制他们的代码.
关于这是主观的:当然是,并且可能没有正确的答案,但我认为它仍然完美在家.从比我更好的程序员那里获得建议是第二种最好的学习方式.主观问题正是谷歌无法回答的问题.
我知道你在想什么 - "噢,天哪,认真,不再" - 但请耐心等待,我的问题不仅仅是标题.在开始之前,我保证永远不会尝试用正则表达式解析任意HTML,或者问别人怎么做.
这里解释为什么你不能这样做的所有许多答案都依赖于正则表达式的正式定义.它们解析常规语言,HTML是无上下文但不是常规的,所以你不能这样做.但我也听说过各种语言的许多正则表达式实现都不是严格规范的; 他们带来了超出正式正则表达范围的额外技巧.
由于我不知道任何特定实现的细节,例如perl,我的问题是:
我最近问过正确地做DI,并获得了一些关于它的博客文章的链接.我想我现在有了更好的理解 - 通过将它放在工厂中,将逻辑分离出来.但是所有的例子都是针对像网站这样的东西,并且说要在启动时做所有的接线.调用一个大工厂,它可以new传递所有依赖关系.
但是,如果我不想在前面实例化所有内容呢?我有一个对象,其中包含可以委派给的其他对象的列表,但它们很昂贵,并且一次只使用一个,所以我在需要时构建它们,并在完成后让它们被收集.我不想把它new B()放在逻辑中A因为我宁愿使用DI - 但是如何?可以A打电话给工厂吗?除非工厂维持包括当前依赖关系的状态,否则这似乎并没有好多少.我只是不想将Bs 的完整列表传递到A构造时,因为它会浪费.如果你愿意,B不一定必须在里面A,虽然它具有逻辑意义(A是一个游戏级别,B是一个单一的屏幕),但无论如何,逻辑A决定何时B创建.
那么,谁叫工厂得到B,什么时候?
澄清:我没有使用DI的框架.我想知道DI一词是否意味着?
我在一段时间内决定重构一些游戏战斗代码,尝试装饰模式.战斗员可以拥有各种被动技能,也可能是不同类型的生物.我认为装饰器允许我在运行时添加各种组合的行为,所以我不需要数百个子类.
我几乎完成了为被动技能制作大约15个装饰器,并且在测试中我发现了一些东西 - 装饰器模式的一个相当明显的缺点,我很惊讶我以前没有听说过.
要使装饰器工作,必须在最外面的装饰器上调用它们的方法.如果"基类" - 包装对象 - 调用它自己的方法之一,那么该方法将不是装饰重载,因为调用无法被"虚拟化"到包装器.人工子类的整个概念被打破了.
这是一件大事.我的战斗员拥有的方法TakeHit反过来称他们自己的Damage方法.但装饰Damage并没有被调用.
也许我选择了错误的模式或者在其应用中过于热心.在这种情况下,您是否对更合适的模式有任何建议,或者解决这个缺陷的方法?我重构的代码只是把所有的被动能力都洒if在看似随机的地方里面的战斗代码中,所以这就是为什么我要打破它.
public function TakeHit($attacker, $quality, $damage)
{
$damage -= $this->DamageReduction($damage);
$damage = round($damage);
if ($damage < 1) $damage = 1;
$this->Damage($damage);
if ($damage > 0)
{
$this->wasHit = true;
}
return $damage;
}
Run Code Online (Sandbox Code Playgroud)
此方法位于基Combatant类中.DamageReduction并且Damage可以并且都被覆盖在各种装饰器中,例如被动器将伤害减少四分之一,或者另一个反射器将一些伤害反射回攻击者.
class Logic_Combatant_Metal extends Logic_Combatant_Decorator
{
public function TakeHit($attacker, $quality, $damage)
{
$actual = parent::TakeHit($attacker, $quality, $damage);
$reflect = $this->MetalReflect($actual);
if ($reflect …Run Code Online (Sandbox Code Playgroud) 我刚刚读了一些关于主题的相关问题,所以我会尽量不重复这些问题.
我最近开始重新审视一个我在两三年前开始的学习项目 - 一个Mega Man引擎的C++端口.是的我用过撕裂的精灵.我还使用游戏引擎库进行绘图,音乐和输入.
我的原始代码是残暴的.虽然它可以(但几乎没有)被称为OO,但它完全忽略了这一点.我开始添加类似接口的东西,并删除了大量重复的代码.有一些我不确定的事情,因为游戏设计有时变得非常复杂.
代表我的游戏库的对象目前是全局的(我知道全局变量通常很糟糕),因为许多对象可能会依赖它来加载艺术或音乐.什么是将该对象从全局范围中拉出来的最佳方法,而不必将50个参数传递给否则将直接使用它的所有内容?
下一个问题:众所周知,Mega Man会射出许多小小的白色射弹.目前,Player对象负责他发射的Projectile对象,更新它们的位置等(字面意思是,在Player :: Update()方法中,每次镜头调用一次Projectile :: Update()方法).这是错误的方法吗?我的第一个改进是让所有这些对象实现了DrawingObject接口,这样我的游戏就可以绘制所有内容.为Updates做同样的事情意味着我将玩家的控制权从玩家手中夺走并将其交给更广泛的Game对象.我对此犹豫不决的原因是它感觉像上帝对象反模式.或者我误解了反模式?还有其他复杂性 - 射弹如果离开可见屏幕就会死亡,因此任何更新射弹的调用都需要调用者能够访问屏幕对象.
这一切都是现在,当我到达他们时,我会回来遇到更多问题.第一篇文章结束!
我在让我的游戏引擎在我兄弟的机器上运行时遇到了问题,该机器运行的是64位Windows 7.我正在使用32位XP SP2进行开发.
我的应用程序使用XNA,FMOD.NET和我在C#中完全编写的另一个dll.一切都针对x86,而不是AnyCPU.我已经读过,这是XNA工作所必需的,因为没有64位的xna框架.我将FMOD.NET重新编译为x86,并确保使用32位版本的本机dll.所以我没有看到任何问题.
然而,当他试图运行我的应用程序时,它给出了一个神秘的错误,但并非闻所未闻.
A FileNotFoundException具有空文件名,并且堆栈跟踪的顶部位于我的主窗体构造函数中.信息是The specified module could not be found. (Exception from HRESULT: 0x8007007E)
我在网上发现了一些关于这个错误的线索,所有这些都是非常模糊,混合和模糊的反应,并没有真正帮助我.大多数提醒人们瞄准x86.有人说检查他们是否有必要的所有dll.
我给了我的兄弟Microsoft.Xna.Framework.dll,但他是否需要安装整个XNA可再发行组件包?当我拿走他寄给他的所有内容并将其粘贴在一个随机目录中时,它对我来说仍然运行良好.我在VS2008中开发了游戏,而不是在游戏工作室,使用XNA 3.0和使用XNA绘图的Windows窗体控件,这是我在msdn教程中找到的.如果可能的话,我还想避免要求完整的安装程序.
任何见解?请?
这个问题有点类似于this one,但不完全相同。我有一个 C# 游戏引擎,我正在与一些想要使用我的引擎的人一起工作。最初我设计了引擎,以便所有资产都是外部的——非程序员可以创建艺术、音乐、xml 设置等,并且任何人都可以修改现有游戏,并在彼此之间共享。基本上包括引擎本身在内的整个事情都是开源的。
我正在与之合作的小组(目前仅有的两个使用我的引擎的项目之一)想要关闭他们的资产,以便无法修改它们。尽管这违反了我的原则,但我不想拒绝他们,因为我已经与他们合作了一段时间,而且市场非常小(对于像我这样的引擎以及这些引擎的用户而言)。
有没有办法,也许是一些可用的软件,可以将一个exe和一堆其他任意文件粉碎成一个exe,而不仅仅是一个存档?我希望最终 exe 的行为就像它运行第一个 exe 一样,其中包含一些引用捆绑文件的命令行参数。例如,运行bundle.exe就像运行一样,original.exe --project_path=/project但项目文件在包内,无法从中检索。
我原来的 exe 是用 C# 编写的。我怀疑这很重要。