在试图找出CLIM时,我遇到了这个示例程序。这是个简单的迷宫游戏。作者声称已经在LispWorks中测试过它(甚至还有#+Genera,这意味着这个程序可以在一个真正的Lisp上工作),但是我想让它在SBCL中使用McCLIM。
在SBCL/McCLIM下,窗口会绘制,但是当您按下移动键时,不会出现任何可见的情况。非移动键导致文本被输入到带有游戏说明的窗格中。
我发现游戏命令键正在改变游戏的内部状态,所以唯一的问题是屏幕不更新。
然后我意识到,您不能编写代码从实现命令的代码范围中重新绘制迷宫。所有绘制的方法都接收来自CLIM的stream参数,该参数必须传递给图形原语。例如:
(defun draw-stone (stream x y cell-width cell-height)
(let ((half-cell-width (/ cell-width 2))
(half-cell-height (/ cell-height 2)))
(draw-ellipse* stream
(+ (* x cell-width) half-cell-width)
(+ (* y cell-height) half-cell-height)
half-cell-width 0
0 half-cell-height
:ink +red+)))但是处理击键的代码没有收到stream参数:
(defmacro define-stone-move-command (name keystroke dx dy)
`(define-maze-frame-command (,name :keystroke ,keystroke) ()
(let ((maze-array (maze-array *application-frame*)))
(move-stone maze-array ,dx ,dy)
(check-for-win maze-array))))最后,我必须将stream参数从对draw-maze-array的第一个(也是唯一)调用中保存到全局变量中,这样我就可以向define-stone-command宏添加更新代码,如下所示:
(defmacro define-stone-move-command (name keystroke dx dy)
`(define-maze-frame-command (,name :keystroke ,keystroke) ()
(let ((maze-array (maze-array *application-frame*)))
(move-stone maze-array ,dx ,dy)
(check-for-win maze-array)
(draw-maze-array *application-frame* *maze-stream*))))这种轻微的更改在SBCL上给出了McCLIM所需的行为,但这似乎不正确。毕竟,作者声称代码在LispWorks上运行得很好。我有几个问题:
发布于 2015-06-10 18:25:59
在命令中绘制迷宫不是正确的方法。将迷宫流放入全局变量也是不好的。;-)
显示窗格有一个:display-function。其思想是,在一个命令之后,整个应用程序框架就会自动更新。例如,对于:display-time :command-loop,将在命令运行后自动更新显示窗格。还有其他更新窗格的方法,但在本例中,击键运行一个命令,然后顶层循环将调用每个适用窗格的显示函数。默认的toplevel循环读取命令(通过鼠标、命令行、击键、.),在循环中执行它并更新应用程序框架。
整个重新显示是非常棘手的/强大的。它允许从完全自动化的重新显示机制到非常细粒度的控制.
你可以在这里读到:CLIM 2规格。注意:规范与实现提供的.之间可能有很大的差别.
https://stackoverflow.com/questions/30761206
复制相似问题