Python从零模仿我的世界(十四)

本文讲解了如何在OpenGL中使用set2d和set3d函数切换2D和3D模式,并介绍如何通过鼠标移动和键盘事件实现游戏中的自由移动。重点在于处理鼠标滚轮和键盘WASD控制的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

显示

这篇文章我们来讲set3d函数和它的“近亲”set2d函数。它们长成这个样子:

class Window(...):
    ...
    def set_2d(self):
        # get_size 函数是继承来的
        width, height = self.get_size()
        glDisable(GL_DEPTH_TEST)
        # get_viewport_size 函数也是继承来的
        viewport = self.get_viewport_size()
        # 接下来的代码大致就是把在3d空间的画面投影到2d画面上
        glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1]))
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, max(1, width), 0, max(1, height), -1, 1)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

    def set_3d(self):
        width, height = self.get_size()
        glEnable(GL_DEPTH_TEST)
        viewport = self.get_viewport_size()
        # 接下来就是恢复一下3d显示模式
        glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1]))
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(65.0, width / float(height), 0.1, 60.0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        x, y = self.rotation
        glRotatef(x, 0, 1, 0)
        glRotatef(-y, math.cos(math.radians(x)), 0, math.sin(math.radians(x)))
        x, y, z = self.position
        glTranslatef(-x, -y, -z)

这里具体的原理我们先不说了,大家只要知道绘制3d图形前要调用set3d函数,而绘制2d图形前要调用set2d函数就行了。感兴趣的话可以在评论区讨论,或者在网上搜索“OpenGL视口”。
现在我们的游戏又能运行又能显示了,如果能加上自由移动的功能的话就更好了。

自由移动

自由移动要分两部分来实现,分别是处理鼠标事件和键盘事件。

鼠标事件

这里我们要处理的不是鼠标按下,而是鼠标移动。鼠标移动的事件处理函数名是on_mouse_motion哦。

class Window(...):
    ...
    def on_mouse_motion(self, x, y, dx, dy):
        # x 表示的是鼠标的 x 坐标
        # y 表示的是鼠标的 y 坐标
        # dx 表示的是鼠标现在的 x 坐标和上一次的差值
        # dy 表示的是鼠标现在的 y 坐标和上一次的差值
        m = 0.15
        # 呼~这里又是算法了
        # 感兴趣的话可以在评论区讨论
        x, y = self.rotation
        x, y = x + dx * m, y + dy * m
        y = max(-90, min(90, y))
        self.rotation = (x, y)

键盘事件

键盘按下和弹起的事件处理函数名分别是on_key_presson_key_release。代码很简单,我们这样写:

class Window(...):
    ...
    def on_key_press(self, symbol, modifiers):
        # symbol 是按键名,各种不同的按键名都是定义在 pyglet.window.key 中的
        # modifiers 我们先不用管
        if symbol == pyglet.window.key.W:
            self.strafe[0] -= 1
        elif symbol == pyglet.window.key.S:
            self.strafe[0] += 1
        elif symbol == pyglet.window.key.A:
            self.strafe[1] -= 1
        elif symbol == pyglet.window.key.D:
            self.strafe[1] += 1

    def on_key_release(self, symbol, modifiers):
        if symbol == pyglet.window.key.W:
            self.strafe[0] += 1
        elif symbol == pyglet.window.key.S:
            self.strafe[0] -= 1
        elif symbol == pyglet.window.key.A:
            self.strafe[1] += 1
        elif symbol == pyglet.window.key.D:
            self.strafe[1] -= 1

这里的代码就是一个对WSAD前后左右移动的处理。不过如果代码写成这样的话玩起来会很不舒服,大家知道玄机在哪吗?欢迎评论区讨论哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值