Python PyGame做3d游戏吗?

Python PyGame做3d游戏吗?,python,3d,pygame,Python,3d,Pygame,我似乎到处都找不到这个问题的答案。我知道你必须使用PyOpenGL或类似的东西来做OpenGL的东西,但我想知道是否有可能在没有任何其他依赖项的情况下制作非常基本的3D图形。不,Pygame是SDL的包装器,SDL是一个2D api。Pygame不提供任何3D功能,可能永远也不会提供 Python的3D库包括和,尽管它们的使用可能相当复杂,尤其是后者。好吧,如果你能做2d,你总是可以做3D。所有3d实际上都是倾斜的二维表面,给人的印象是你在看有深度的东西。真正的问题是它能做得好吗,你会愿意吗。浏

我似乎到处都找不到这个问题的答案。我知道你必须使用PyOpenGL或类似的东西来做OpenGL的东西,但我想知道是否有可能在没有任何其他依赖项的情况下制作非常基本的3D图形。

不,Pygame是SDL的包装器,SDL是一个2D api。Pygame不提供任何3D功能,可能永远也不会提供


Python的3D库包括和,尽管它们的使用可能相当复杂,尤其是后者。

好吧,如果你能做2d,你总是可以做3D。所有3d实际上都是倾斜的二维表面,给人的印象是你在看有深度的东西。真正的问题是它能做得好吗,你会愿意吗。浏览pyGame文档一段时间后,它看起来只是一个SDL包装器。SDL不适用于3d编程,所以真正问题的答案是,不,我甚至不想尝试。

Python Soya可以在pygame表面上渲染3d图形。

您只能使用pygame进行类似Doom这样的伪3d游戏:

如果您浏览pygame.org网站,您可能会发现更多使用python和pygame完成的3d游戏


然而,如果你真的想进入3d编程领域,你应该研究OpenGl、Blender或任何其他真正的3d库。

如果你想要3d投影功能和所有这些东西,你必须使用3d API,但如果你想做一个基本的3d外观,我推荐Peter的网站教程:

Pygame本来就不打算做3d,但是有一种方法可以使用任何2d图形库进行3d。您所需要的只是以下函数,该函数将三维点转换为二维点,允许您通过在屏幕上绘制线来生成任何三维形状

def convert_to_2d(point=[0,0,0]):
    return [point[0]*(point[2]*.3),point[1]*(point[2]*.3)]

这被称为伪3d,或2.5d。这是可以做到的,但速度可能很慢,而且非常难做到,因此建议您使用3d库。

为PyGame制作3d驱动程序很容易。PyGame拥有一些用于3D游戏开发的资产。
我现在正在使用PyGame开发Py3D驱动程序。当我完成时,我将向您显示下载Py3D的链接。我试着用PyGame制作3D游戏,我只需要PyGame的一个小插件。你认为必须使用SDL、PyOpenGL、OpenGL、PyQt5、Tkinter是错误的。他们制作3D游戏都是错误的。OpenGL和PyOpenGL或Panda3D非常难学。我在那些车手身上玩的所有游戏都很糟糕。PyQt5和Tkinter不是制作游戏的驱动程序,但它们有插件。不要试图对那些车手耍花招。我们需要使用数学模块的所有驱动程序都很难。你可以很容易地为他们制作小插件,我想每个人都可以在1-2周内为PyGame制作驱动程序。

你所看到的3D实际上是2D游戏。毕竟,你是在看你的屏幕,这是正常的;是二维的。三维虚拟世界被投影到一个平面上,然后显示在屏幕上。然后,我们的大脑将2D图像转换成3D图像,就像我们眼睛的图像一样,让它看起来像3D

所以制作3D游戏相对容易:你只需使用多维矩阵创建一个虚拟世界,然后将每个循环投影到2D平面上,并显示在屏幕上


使用pygame,您可以在3D程序中使用的一个教程是。

pygame只是一个用于更改像素颜色的库,以及一些其他用于编程游戏的有用内容。您可以通过在屏幕上快速显示图像或直接设置像素的颜色来实现这一点

正因为如此,用pygame编写2D游戏很容易,因为以上就是您真正需要的。但3D游戏只是将一些3D对象“挤压”成2D,以便在屏幕上显示。因此,要仅使用pygame制作3D游戏,您必须自己处理此渲染,包括所有必要的复杂矩阵数学

这不仅会因为涉及到巨大的处理能力而运行缓慢,而且还需要编写一个大规模的3D渲染/光栅化引擎。由于python被解释,它的速度会更慢。正确的方法是使用Pyopengl在GPU上运行这个过程


所以,是的,仅使用pygame制作3D在技术上是可行的,但绝对不推荐。我建议您学习Panda3D或类似的3D引擎。

您可以这样制作:

def convert_2dx,y,z,地平线: d=1-z/地平线 返回x*d,y*d def绘制点列表列表列表: '假设lst是一个3维点列表,如[0,0,0,1,6,2…”。。。 让我们以200为地平线,它可以给我们一个非常干净的3D' 对于lst中的x、y、z: pygame.draw.circlescreen,颜色,转换\u 2dx,y,z,200,1 但是它不是很快。如果你想要快速,试着用C++/SDL2或C实现。 Pygame不太适合3d图形。

简单: 只需绘制一组多边形,如:

导入pygame screen=pygame.display.set_mode100100,100 尽管如此: screen.fill0,0,0 位置=[10,10,20,10,20,20, 10, 20] 前面的第一面是红色的 pygame.draw.Polygon屏幕,225,0,0,位置 白色轮廓 pygame.draw.linesscreen,225,225,位置 背面是蓝色的 Pos2=[Pos[0[0]]+2.5,Pos[0[1]]+2.5,Pos2[0[0]+5,Pos2[0[1]],Pos2[1[0]],Pos2[1[1]+5,Pos2[0[0]],Pos2[0[1]+5] pygame.draw.Polygon屏幕,0,0,225,位置2 pygame.draw.linesscreen,225,225,位置2 第三面是左边,但只有两条线不是真正的绿色 Pos3=[Pos[0],Pos2[0],Pos2[3],Pos[3]] pygame.draw.Polygon屏幕,0,225,0,位置3 pygame.draw.linesscreen,225,225,位置3 右边是紫色的第四面 位置4=[Pos[1],Pos2[1],Pos2[2],Pos[2]] pygame.draw.Polygon屏幕,225,0,225,位置4 pygame.draw.linesscreen,225,225,位置4 pygame.display.flip &有一个简单的立方体&我将很快为完整的代码提供一个链接,以便能够旋转立方体并调整其大小


这将为您提供与使用OpenGL所获得的功能相当的功能。Pygame不提供任何用于绘制3D形状、网格甚至透视和照明的功能。 如果要使用Pygame绘制3D场景,则需要使用向量算法计算顶点,并使用多边形将几何体缝合在一起。 然后回答以下问题的示例:

这种方法不会产生令人满意的性能,只对学习有价值。3D场景是在GPU的帮助下生成的。仅CPU的方法无法达到所需的性能

在Python中使3D场景更强大的一种方法是使用基于OpenGL的库,如或

但是,您可以使用Pygame窗口创建一个。创建显示曲面时,需要设置pygame.OPENGL标志。请参见:

window=pg.display.set_modewidth,height,pygame.OPENGL | pygame.DOUBLEBUF 请参见示例:

导入pygame 从OpenGL.GL导入* 从OpenGL.GLU导入* 从OpenGL.GL.shaders导入* 导入ctypes 进口glm glsl_垂直= 330版核心 vec3 a_位置中的布局位置=0; 布局位置=矢量4列中的1; 输出vec4 v_颜色; 统一材料工程; 统一的mat4 u_视图; 统一mat4-u_模型; 真空总管 { v_color=a_col; gl_位置=u_项目*u_视图*u_模型*vec4a_位置xyz,1.0; } glsl_frag= 330版核心 输出vec4 frag_颜色; 在vec4 v_颜色中; 真空总管 { frag_color=v_color; } 类多维数据集: 定义初始自我: v=[-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1] 边=[0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7] 表面=[0,1,2,3,5,4,7,6,4,0,3,7,1,5,6,2,4,5,1,0,3,2,6,7] 颜色=[1,0,0,0,1,0,0,1,1,1,0,1,1,0,1,1,0.5,0] 线条颜色=[0,0,0] 边缘_属性=[] 对于边中的e: 边_属性+=v[e[0]] 边缘属性+=线条颜色 边_属性+=v[e[1]] 边缘属性+=线条颜色 面_属性=[] 对于i,枚举曲面中的四边形: 对于四合院的iv: 面_属性+=v[iv] 面_属性+=颜色[i] self.edge_vbo=glGenBuffers1 glBindBufferGL_数组_缓冲区,self.edge_vbo glBufferDataGL_数组_缓冲区,GLfloat*lenedge_属性*edge_属性,GL_静态_绘制 self.edge_vao=glGenVertexArrays1 glBindVertexArrayself.edge\u vao glVertexAttributePointer0,3,GL_FLOAT,False,6*ctypes.sizeofGLfloat,ctypes.c_void\u p0 GlenableVertexAttribute0 glVertexAttributePointer1,3,GL_FLOAT,False,6*ctypes.sizeofGLfloat,ctypes.c_void_p3*ctypes.sizeofGLfloat GlenableVertexattribute1 self.face_vbos=glGenBuffers1 glBindBufferGL_数组_缓冲区,self.face_vbos glBufferDataGL_数组_缓冲区,GLfloat*lenface_属性*face_属性,GL_静态_绘制 self.face_vao=glGenVertexArrays1 glBindVertexArrayself.face\u vao glVertexAttributePointer0,3,GL_FLOAT,False,6*ctypes.sizeofGLfloat,ctypes.c_void\u p0 GlenableVertexAttribute0 glVertexAttributePointer1,3,GL_FLOAT,False,6*ctypes.sizeofGLfloat,ctypes.c_void_p3*ctypes.sizeofGLfloat GlenableVertexattribute1 def drawself: glEnableGL_深度试验 glLineWidth5 glBindVertexArrayself.edge\u vao glDrawArraysGL_线,0,12*2 glBindVertexArray0 glEnableGL_多边形_偏移_填充 glPolygonOffset 1.0,1.0 glBindVertexArrayself.face\u vao GLDRAWARRAYSGLU四边形,0,6*4 glBindVertexArray0 GLDISABLEGLU多边形偏移填充 def set_项目W、h: 返回glm透视glm弧度45,w/h,0.1,50.0 pygame.init window=pygame.display.set_mode400300,pygame.DOUBLEBUF | pygame.OPENGL | pygame.resizeable clock=pygame.time.clock proj=设置投影*窗口。获取大小 视图=glm.lookAtglm.vec30,0,5,glm.vec30,0,0,glm.vec30,1,0 型号=glm.mat41 立方体=立方体 角度x, 角度y=0,0 程序=编译程序 编译着色器glsl_vert、GL_VERTEX_着色器, 编译着色器glsl_frag、GL_FRAGMENT_着色器 attrib={a:glGetAttribLocationprogram,a代表['a_pos','a_col']}中的a 打印属性 uniform={u:glGetUniformLocationprogram,u代表['u_模型','u_视图','u_项目']} 印花制服 GLUSEPROGRAM程序 运行=真 运行时: 时钟滴答滴答 对于pygame.event.get中的事件: 如果event.type==pygame.QUIT: 运行=错误 elif event.type==pygame.VIDEORESIZE: glViewport0,0,event.w,event.h proj=set_projectionevent.w,event.h 型号=glm.mat41 模型=glm.rotatemodel,glm.radiansangle__y,glm.vec30,1,0 模型=glm.rotatemodel,glm.radiansangle_x,glm.vec31,0,0 glUniformMatrix4fvuniform['u_proj'],1,GL_FALSE,glm.value_ptrproj glUniformMatrix4fvuniform['u_view'],1,GL_FALSE,glm.value_ptrview glUniformMatrix4fvuniform['u_model'],1,GL_FALSE,glm.value_ptrmodel 角度_x+=1 角度_y+=0.4 glClearColor0.5,0.5,0.5,1 glClearGL_颜色_缓冲_位| GL_深度_缓冲_位 立方体绘制 pygame.display.flip pygame.退出 出口
如果你想在制作游戏时坚持使用python风格的语言,Godot是一个很好的选择,它提供了2D和3D支持、大型社区和大量教程。它的定制脚本语言gdscript有一些细微的区别,但总体上基本相同。它还支持C和C++,在游戏开发方面有更多的特点。

不支持,但是结合PyOpenGL,你可以利用两者的力量,这里是一个完整的例子

    import pygame
    from pygame.locals import *

    from OpenGL.GL import *
    from OpenGL.GLU import *

    import random

    vertices = ((1, -1, -1),(1, 1, -1),(-1, 1, -1),(-1, -1, -1),(1, -1, 1),(1, 1, 1),(-1, -1, 1),(-1, 1, 1))
edges = ((0,1),(0,3),(0,4),(2,1),(2,3),(2,7),(6,3),(6,4),(6,7),(5,1),(5,4),(5,7))
    surfaces = ((0,1,2,3),(3,2,7,6),(6,7,5,4),(4,5,1,0),(1,5,7,2),(4,0,3,6))
    colors = ((1,0,0),(0,1,0),(0,0,1),(0,1,0),(1,1,1),(0,1,1),(1,0,0),(0,1,0),(0,0,1),(1,0,0),(1,1,1),(0,1,1),)

   
    def set_vertices(max_distance, min_distance = -20):
        x_value_change = random.randrange(-10,10)
        y_value_change = random.randrange(-10,10)
        z_value_change = random.randrange(-1*max_distance,min_distance)
        new_vertices = []
        for vert in vertices:
            new_vert = []
            new_x = vert[0] + x_value_change
            new_y = vert[1] + y_value_change
            new_z = vert[2] + z_value_change
            new_vert.append(new_x)
            new_vert.append(new_y)
            new_vert.append(new_z)
            new_vertices.append(new_vert)
        return new_vertices
            
        


    def Cube(vertices):
        glBegin(GL_QUADS)
        for surface in surfaces:
            x = 0

            for vertex in surface:
                x+=1
                glColor3fv(colors[x])
                glVertex3fv(vertices[vertex])
        glEnd()
        glBegin(GL_LINES)
        for edge in edges:
            for vertex in edge:
                glVertex3fv(vertices[vertex])
        glEnd()

    def main():
        pygame.init()
        display = (800,600)
        pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
        max_distance = 100
        gluPerspective(45, (display[0]/display[1]), 0.1, max_distance)
        glTranslatef(random.randrange(-5,5),random.randrange(-5,5), -40)
        #object_passed = False
        x_move = 0
        y_move = 0
        cube_dict = {}

        for x in range(50):
            cube_dict[x] =set_vertices(max_distance)

        #glRotatef(25, 2, 1, 0)

        
        x = glGetDoublev(GL_MODELVIEW_MATRIX)
        camera_x = x[3][0]
        camera_y = x[3][1]
        camera_z = x[3][2]
        button_down = False
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
                if event.type == pygame.MOUSEMOTION:
                    if button_down == True:
                        print(pygame.mouse.get_pressed())
                        glRotatef(event.rel[1], 1, 0, 0)
                        glRotatef(event.rel[0], 0, 1, 0)
            
            for event in pygame.mouse.get_pressed():
                # print(pygame.mouse.get_pressed())
                if pygame.mouse.get_pressed()[0] == 1:
                    button_down = True
                elif pygame.mouse.get_pressed()[0] == 0:
                    button_down = False

           

            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)


            for each_cube in cube_dict:
                Cube(cube_dict[each_cube])

            pygame.display.flip()
            pygame.time.wait(10)

    main()
    pygame.quit()
    quit()

这有什么不对?Pygame不支持3d。PyOpenGL不支持3d。重读他的问题。是的,我正在写一个3D游戏。我甚至没有使用OpenGL。我正在使用霍斯特·延斯张贴的方法。我已经尝试过了。事实上,我以前在C++中编写了一个OpenGL的整体仿真。这很糟糕,学习真正的3D API是一个更好的主意,直到你知道你在用3D技术做什么。这是正确的,但是如果目的是像其他引擎开发的大多数3D游戏那样实际使用3D资产,PyGame就不可能做到这一点。可能是某种类型的导入器,可以将3D转换为所需视图中的固定图像,但这将在实现中受到严重限制,因为这将是一项巨大的工作。