显示
这篇文章我们来讲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_press
和on_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前后左右移动的处理。不过如果代码写成这样的话玩起来会很不舒服,大家知道玄机在哪吗?欢迎评论区讨论哦~