【问题标题】:Getting input with IUP in Lua在 Lua 中使用 IUP 获取输入
【发布时间】:2012-12-13 01:01:36
【问题描述】:

我一直在尝试通过 IUP 获得意见来制作一个小型乒乓球游戏。我想尝试一些输入,并尝试了 IUPGL 示例附带的一些代码,但输入似乎根本不起作用。这是目前的代码:

require "iuplua"
require "iupluagl"
require "luagl"

paddle = {x = -0.9, y = 0.2}

function drawPaddle(x, y)
    gl.Begin(gl.QUADS)
    gl.Color(0.0, 0.5, 0.0)

    gl.Vertex(x, y)
    gl.Vertex(x + 0.1, y)
    gl.Vertex(x + 0.1, y - 0.4)
    gl.Vertex(x, y - 0.4)
end

canvas = iup.glcanvas{buffer = "DOUBLE", rastersize = "300x300"}

function canvas:action(x, y)
    iup.GLMakeCurrent(self)
    gl.ClearColor(0.0, 0.0, 0.0, 0.0)
    gl.Clear(gl.COLOR_BUFFER_BIT)
    gl.Clear(gl.DEPTH_BUFFER_BIT)

    gl.MatrixMode(gl.PROJECTION)
    gl.Viewport(0, 0, 300, 300)
    gl.LoadIdentity()

    drawPaddle(paddle.x, paddle.y)

    gl.End()
    iup.GLSwapBuffers(self)
end

window = iup.dialog{canvas, title = "Soon to be Pong"}

function canvas:k_any(c)
    if c == iup.K_q then
        return iup.CLOSE
    elseif c == iup.K_w then
        paddle.y = paddle.y + 0.02
        return iup.CONTINUE
    else
        return iup.DEFAULT
    end
end

window:show()

iup.MainLoop()

据我了解,当按下某个键时会调用 canvas:k_any(),但它没有响应,即使是退出命令也是如此。有什么想法吗?

【问题讨论】:

  • 您可能应该向 IUP 邮件列表 lists.luaforge.net/cgi-bin/mailman/listinfo/iup-mail 或 Lua 邮件列表 bazar2.conectiva.com.br/mailman/listinfo/lua 提出这个问题 IUP 作者正在阅读它们,并且通常非常有帮助和响应。
  • 我在几个项目中使用了 IUP,但还没有玩过 IUPGL。虽然,我可能应该将它而不是 CD 用于我必须为一个项目实现的音频电平表控制......我确实知道 Lua 绑定中的关键回调比直接从 C 中使用 IUP 时更奇怪,所以这可能是开始查看源代码的地方。我将支持尝试 IUP 列表的建议。作者通常会迅速做出反应,您也会接触到许多高级用户。

标签: lua iup


【解决方案1】:

这至少是您引用的示例的部分问题。在iup 表中实际定义 IUP 键名常量之前,您需要调用一个函数。这个想法是,如果您不需要所有的键名,那么内存占用会更低,许多应用程序完全不需要这些键名。

尝试在require "iuplua" 之后不久和在任何代码中使用名称之前添加以下行:

iup.key_open() -- 加载键名

这记录在键盘代码主题的顶部附近以及与键盘相关的多个位置。

如果不调用 iup.key_open()iup.K_q 的计算结果为 nil(与任何其他键名一样),因此永远不会匹配传递给 canvas:k_any() 的任何键码。

编辑:我刚刚运行了您的示例,确实调用 iup.key_open() 会导致 q 和 w 键被识别。接下来您会注意到一个进一步的故障,即仅更新桨的位置并不要求重新绘制画布。在你继续前进时,我会把它作为练习。

Edit2: 将行 iup.Update(self) 添加到函数 canvas:k_any() 之后,就在您修改桨的状态后,似乎可以满足您的需求。这样做而不是手动调用action() 方法具有以预期方式与IUP 的消息循环处理交互的优点。在一般情况下,可能首选调用iup.UpdateChildren(window)。这将使对话框中显示的任何其他 IUP 控件以及画布保持更新,如果您的控件不会在内部进行所有自己的更新,这将很有用。

或者,您可以将绘图例程移动到它们自己的函数中,这些函数由画布的k_any()action() 方法调用。我不确定我是否会推荐它,因为当您想要支持多个视口或相关控件时,它的缩放效果也不好。

您可能希望重新排列 k_any() 处理程序中的逻辑,以便在为新键添加案例时不太可能意外忘记对 iup.Update() 的调用。

【讨论】:

  • 我怀疑密钥是nil,感谢您确认!我目前正在查看文档,试图弄清楚如何强制重绘,但运气不佳。我试过iup.Updateiup.UpdateChildren,但它抱怨它们是nil 值。
  • 好吧,我已经设法让它工作了,但它似乎有点笨拙。在canvas:k_any()的最后,我直接调用canvas:action()。这样就完成了工作,但有没有更好的方法来强制重绘?
  • 我编辑了一些关于在 canvas:k_any(key) 方法中在何处以及如何调用 iup.Update(self) 的说明。
  • iup.key_open() 在 IUP 3 中不再需要。
猜你喜欢
  • 2012-08-17
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-10
  • 1970-01-01
相关资源
最近更新 更多