在试图找出CLIM时,我遇到了this example program。这是一个简单的迷宫游戏。作者声称已经在LispWorks中测试过它(甚至在那里有#+Genera
,暗示这个程序可以在真正的Lisp机器上运行),但是我试图让它在使用McCLIM的SBCL中工作。
在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
保存到全局变量,以便我可以将更新代码添加到{{ 1}}宏如下:
define-stone-command
这种轻微的改变在使用McCLIM的SBCL上给出了期望的行为,但是这似乎不正确。毕竟,作者声称代码在LispWorks上运行良好。我有几个问题:
答案 0 :(得分:1)
在命令中绘制迷宫不是正确的方法。将迷宫流放入全局变量也很糟糕。 ; - )
显示窗格有:display-function
。这个想法是在命令之后整个应用程序框架自动更新。例如,对于:display-time
:command-loop
,显示窗格将在命令运行后自动更新。还有其他方法可以更新窗格,但在这种情况下,按键会运行一个命令,然后顶级循环只会为每个适用的窗格调用 display-function 。默认的toplevel-loop读取命令(通过鼠标,命令行,按键等...),执行它并更新应用程序框架 - 循环。
整个重新显示的东西非常棘手/强大。它允许从完全自动化的重新显示机制到极细粒度的控制。
您可以在此处阅读:CLIM 2 Spec。注意:规范与实现提供的内容之间可能存在相当大的差异......