我喜欢单元测试的想法,但我在将它应用于游戏编程时遇到了麻烦.游戏非常有状态,而且代码通常不会分解成不同的单元.根据我的经验,大多数函数都会改变状态而不是返回值.
考虑一个简单的动作playerJump(height)
.我希望有一个测试套件可以检查各种各样的情况,以确保跳跃始终按预期工作.然而,这个功能可能会不返回值,并有副作用,player.velocity.y = -height
和checkCollisions(player)
.我想不出一个明确的单元测试来构建这个.
单元测试在游戏等高度有状态的应用程序中是否不可行?单元测试的优势是否如此之大,以至于值得在功能上编程游戏?
更新:
来自Within的游戏有一系列关于在游戏中使用测试驱动开发的深度文章.我强烈推荐给任何对此主题感兴趣的人.这是第一篇文章:
http://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-1
Gaffer on Games有一篇很棒的文章,关于使用RK4集成来改进游戏物理.实现很简单,但背后的数学让我感到困惑.我从概念层面理解衍生物和积分,但很长一段时间没有操纵方程式.
这是Gaffer实施的主要内容:
void integrate(State &state, float t, float dt)
{
Derivative a = evaluate(state, t, 0.0f, Derivative());
Derivative b = evaluate(state, t+dt*0.5f, dt*0.5f, a);
Derivative c = evaluate(state, t+dt*0.5f, dt*0.5f, b);
Derivative d = evaluate(state, t+dt, dt, c);
const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv)
state.x = state.x + dxdt * dt;
state.v = state.v …
Run Code Online (Sandbox Code Playgroud) 有哪些语言可以促进面向对象和函数式编程?我知道任何支持一流功能的语言都可以被认为是功能性的,但我正在寻找一种专门针对两种编码风格的语法.
使用这样的语言,我想象将所有状态更改隔离到单个代码部分,并使程序的其余部分纯粹功能.只是想到它让我流口水(调试天堂!).
到目前为止,我已经发现了Scala,虽然我刚刚听说过它(它看起来很神奇).在这种"混合风格"范式中是否有任何重要的竞争者?
我正在尝试从网站上提供的API和文档中学习Clojure.我对Clojure中的可变存储有点不清楚,我想确保我的理解是正确的.如果有任何想法我错了,请告诉我.
编辑:我正在更新这个,因为我收到有关其正确性的评论.
免责声明:所有这些信息都是非正式的,可能是错误的.不要使用这篇文章来了解Clojure的工作原理.
Vars总是包含根绑定,可能还包含每个线程的绑定.它们与命令式语言中的常规变量相当,不适合在线程之间共享信息.(感谢Arthur Ulfeldt)
Refs是支持原子事务的线程之间共享的位置,可以更改单个事务中任意数量的ref的状态.在退出同步表达式(dosync)时提交事务,并且使用STM魔法(回滚,队列,等待等)自动解决冲突
代理是通过调度独立的操作函数来更改代理的状态,使得线程之间异步共享信息的位置,而开销最小.虽然在调度函数完成之前未设置代理程序的值,但代理程序会立即返回并因此是非阻塞的.
原子是可以在线程之间同步共享的位置.它们支持不同线程之间的安全操作.
这是我基于何时使用这些结构的友好总结:
此外,相关概念是功能future
.对我来说,似乎未来的对象可以被描述为同步代理,在完成计算之前根本无法访问该值.它也可以描述为非阻塞Atom.这些准确的未来概念是什么?
在文档中似乎没有明确的答案.
我有兴趣增加一个time
计算程序启动后秒数的变量.如果最大值可以计入未来,例如100年,那么我不关心让变量永远增量.否则我将不得不考虑重置time
为0 的好点.
最近我试图向我的项目经理解释一些设计糟糕的代码.所有的管理器类都是单例("这就是为什么我不能轻易改变它")并且代码使用事件调度,函数调用就足够了("这就是为什么它很难调试").可悲的是,它只是一个笨拙的英语混乱.
您作为程序员向非技术人员传达的最困难的事情是什么?您是否发现任何类比或解释方法使其更清晰?
将关键字作为可选标志实现到函数的最佳方法是什么?我想进行函数调用,例如:
(myfunction 5)
(myfunction 6 :do-this)
(myfunction 3 :go-here)
(myfunction 2 :do-this :do-that)
Run Code Online (Sandbox Code Playgroud)
使用defn,我可以定义一个函数,例如:
(defn myfunction [value & flags] ... )
Run Code Online (Sandbox Code Playgroud)
但这flags
成了一个清单.我可以编写自己的函数来搜索列表,但是这样的函数不包含在核心库中,所以我认为它不是惯用的.
我现在用的是什么:
(defn flag-set? [list flag] (not (empty? (filter #(= flag %) list))))
(defn flag-add [list flag] (cons flag list))
(defn flag-remove [list flag] (filter #(not= flag %) list))
Run Code Online (Sandbox Code Playgroud) 我想使用变量的值来计算同一let语句中另一个变量的值.有没有办法在Clojure中执行此操作而不使用嵌套的let?
嵌套让解决方案:
(let [x 3]
(let [y (+ 1 x)]
y)) = 4
Run Code Online (Sandbox Code Playgroud)
期望的解决方案:
(let [x 3
y (+ 1 x)]
y) = 4
Run Code Online (Sandbox Code Playgroud) 当我从现在开始编写代码时,我计划首先将所有内容布置在漂亮,可读的伪代码中,然后围绕该结构实现该程序.
如果我将目前最简单到最难翻译的语言排名,我会说:
Lisp,Python,Lua,C++,Java,C
我知道每种语言都有其优点和缺点,但我专注于伪代码.您使用哪种语言最适合伪代码?我总是喜欢学习新语言.此外,如果您目前使用此技术,我很乐意听到您有关构建实用伪代码的任何提示.
注意:我觉得这是主观的,但每个人的偏好都有明确的答案.我在这里问这个问题是因为SO社区拥有非常广泛的受众,并且很可能建议我不会遇到的语言和技术.
我目前正在制作一个非常大的Flash平台游戏(数百个课程),并处理一个问题,如果你让它停留足够长的话,游戏会慢慢停止.我没有写游戏,所以我只是模糊地熟悉它的内部.一些神秘的症状包括,
查看源代码并使用Flex Profiler,我的主要嫌疑人是,
WeakMethodClosure
占用大量的记忆.我知道在没有看到源的情况下几乎无法告诉我这个问题,所以我只是在寻找可以帮助我缩小范围的花絮.有没有人在他们自己的项目中经历过这种规避性能下降?你的案子是什么原因?
clojure ×3
apache-flex ×1
future ×1
integration ×1
keyword ×1
let ×1
lua ×1
math ×1
memory-leaks ×1
mutable ×1
nested ×1
numbers ×1
parameters ×1
performance ×1
physics ×1
pseudocode ×1
scala ×1
theory ×1
time ×1
unit-testing ×1