在 Lua 中使用 IUP 获取输入

发布于 2024-07-18 08:03:27 字数 1175 浏览 5 评论 0原文

我一直在尝试向 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() ,但它没有响应,甚至没有响应退出命令。 有任何想法吗?

I've been trying to get input with IUP to make a small pong game. I wanted to try some input, and tried some of the code that comes with the IUPGL examples, but the input doesn't seem to be working at all. Here's the code as it stands so far:

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()

It's my understanding that canvas:k_any() gets called when a key is pressed, but it's not responding, even to the quit command. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稚气少女 2024-07-25 08:03:27

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

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

iup.key_open()      -- load key names

这记录在主题 键盘代码 顶部附近以及在与键盘相关的各个地方。

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

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

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

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

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

Here is at least part of the problem for the sample you've quoted. Before the IUP keyname constants are actually defined in your iup table, you need to call a function. The idea is that the memory footprint is lower if you don't need all of the key names, which many applications can do entirely without.

Try adding the following lines sometime shortly after require "iuplua" and before you use the names in any code:

iup.key_open()      -- load key names

This is documented near the top of the topic Keyboard Codes as well as in a variety of places related to the keyboard.

Without the call to iup.key_open(), iup.K_q evaluates to nil (as does any other key name) and thus silently never matches any keycode passed to canvas:k_any().

Edit: I just ran your sample, and indeed calling iup.key_open() causes the q and w keys to be recognized. You have a further glitch you will notice next that just updating the paddle's position doesn't ask for the canvas to redraw. I'll leave that as an exercise as you go forward.

Edit2: Adding the line iup.Update(self) to the function canvas:k_any() just after you modify the state of the paddle appears to do what you want. Doing it that way rather than manually calling the action() method has the advantage of interacting with IUP's message loop handling in the expected way. In the general case, calling iup.UpdateChildren(window) instead might be preferred. That would keep any other IUP controls that are displayed in the dialog updated as well as the canvas, which can be useful if you have controls that don't do all their own updating internally.

Alternatively, you could move the drawing routines into their own function called from both the k_any() and action() methods of the canvas. I'm not sure I'd recommend that in general as it doesn't scale as well when you want to support multiple viewports or related controls.

You might want to rearrange the logic in your k_any() handler so that you are less likely to accidentally forget the call to iup.Update() as you add cases for new keys.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文