8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

PyGame 能做 3d 吗?

dolmok 1月前

38 0

我似乎在任何地方都找不到这个问题的答案。我知道你必须使用 PyOpenGL 或类似的东西来做 OpenGL 的事情,但我想知道是否有可能做非常基本的 3D

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

帖子版权声明 1、本帖标题:PyGame 能做 3d 吗?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由dolmok在本站《numpy》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 不,Pygame 是 SDL 的包装器,SDL 是一个 2D API。Pygame 不提供任何 3D 功能,而且可能永远不会提供。

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

  • 这有什么问题?Pygame 不支持 3d。PyOpenGL 支持 3d。重新阅读他的问题。

  • 是的,我目前正在编写一款 3D 游戏。我甚至没有使用 OpenGL。我正在使用 Horst JENS 发布的方法。

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

  • 我试过了。事实上,我之前用 C++ 编写过 OpenGL 的完整模拟。这很麻烦,而且在你知道使用 3D 技术做什么之前,学习真正的 3D API 是一个更好的主意。

  • 这是正确的,但是如果意图是实际使用 3D 资源(大多数在其他引擎中开发的 3D 游戏都是这种情况),那么使用 PyGame 就不可能了。可能存在某种导入器,可以将 3D 转换为所需视图中的固定图像,但这在实施过程中会受到严重限制,因为工作量巨大。

  • 你可以只使用 pygame 来制作伪 3D 游戏(例如 \'Doom\'):

    http://code.google.com/p/gh0stenstein/

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

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

  • AleV 1月前 0 只看Ta
    引用 9

    在没有其他依赖项帮助的情况下,Pygame 中的 3D 渲染很难实现,并且性能不佳。Pygame 不提供任何绘制 3D 形状、网格甚至透视和照明的功能。
    如果您想用 Pygame 绘制 3D 场景,您需要使用矢量算法计算顶点并使用多边形将几何图形拼接在一起。
    Pygame 绕轴旋转立方体 的答案示例 :

    这种方式性能并不理想,仅具有学习价值。3D场景是借助GPU生成的。单纯使用CPU的方式无法达到所需的性能。

    如何修复射线投射器中的墙体扭曲? 的答案 :

    import pygame
    import math
    
    pygame.init()
    
    tile_size, map_size = 50, 8
    board = [
        '########',
        '#   #  #',
        '#   # ##',
        '#  ##  #',
        '#      #',
        '###  ###',
        '#      #',
        '########']
    
    def cast_rays(sx, sy, angle):
        rx = math.cos(angle)
        ry = math.sin(angle)
        map_x = sx // tile_size
        map_y = sy // tile_size
    
        t_max_x = sx/tile_size - map_x
        if rx > 0:
            t_max_x = 1 - t_max_x
        t_max_y = sy/tile_size - map_y
        if ry > 0:
            t_max_y = 1 - t_max_y
    
        while True:
            if ry == 0 or t_max_x < t_max_y * abs(rx / ry):
                side = 'x'
                map_x += 1 if rx > 0 else -1
                t_max_x += 1
                if map_x < 0 or map_x >= map_size:
                    break
            else:
                side = 'y'
                map_y += 1 if ry > 0 else -1
                t_max_y += 1
                if map_x < 0 or map_y >= map_size:
                    break
            if board[int(map_y)][int(map_x)] == "#":
                break
    
        if side == 'x':
            x = (map_x + (1 if rx < 0 else 0)) * tile_size
            y = player_y + (x - player_x) * ry / rx
            direction = 'r' if x >= player_x else 'l'
        else:
            y = (map_y + (1 if ry < 0 else 0)) * tile_size
            x = player_x + (y - player_y) * rx / ry
            direction = 'd' if y >= player_y else 'u'
        return (x, y), math.hypot(x - sx, y - sy), direction   
    
    def cast_fov(sx, sy, angle, fov, no_ofrays):
        max_d = math.tan(math.radians(fov/2))
        step = max_d * 2 / no_ofrays
        rays = []
        for i in range(no_ofrays):
            d = -max_d + (i + 0.5) * step
            ray_angle = math.atan2(d, 1)
            pos, dist, direction = cast_rays(sx, sy, angle + ray_angle)
            rays.append((pos, dist, dist * math.cos(ray_angle), direction))
        return rays
    
    area_width = tile_size * map_size
    window = pygame.display.set_mode((area_width*2, area_width))
    clock = pygame.time.Clock()
    
    board_surf = pygame.Surface((area_width, area_width))
    for row in range(8):
        for col in range(8):
            color = (192, 192, 192) if board[row][col] == '#' else (96, 96, 96)
            pygame.draw.rect(board_surf, color, (col * tile_size, row * tile_size, tile_size - 2, tile_size - 2))
    
    player_x, player_y = round(tile_size * 4.5) + 0.5, round(tile_size * 4.5) + 0.5
    player_angle = 0
    max_speed = 3
    colors = {'r' : (196, 128, 64), 'l' : (128, 128, 64), 'd' : (128, 196, 64), 'u' : (64, 196, 64)}
    
    run = True
    while run:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False    
        
        keys = pygame.key.get_pressed()
        hit_pos_front, dist_front, side_front = cast_rays(player_x, player_y, player_angle)
        hit_pos_back, dist_back, side_back = cast_rays(player_x, player_y, player_angle + math.pi)
        player_angle += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 0.1
        speed = ((0 if dist_front <= max_speed else keys[pygame.K_UP]) - (0 if dist_back <= max_speed else keys[pygame.K_DOWN])) * max_speed
        player_x += math.cos(player_angle) * speed
        player_y += math.sin(player_angle) * speed
        rays = cast_fov(player_x, player_y, player_angle, 60, 40)
    
        window.blit(board_surf, (0, 0))
        for ray in rays:
            pygame.draw.line(window, (0, 255, 0), (player_x, player_y), ray[0])
        pygame.draw.line(window, (255, 0, 0), (player_x, player_y), hit_pos_front)
        pygame.draw.circle(window, (255, 0, 0), (player_x, player_y), 8)
    
        pygame.draw.rect(window, (128, 128, 255), (400, 0, 400, 200))
        pygame.draw.rect(window, (128, 128, 128), (400, 200, 400, 200))
        for i, ray in enumerate(rays):
            height = round(10000 / ray[2])
            width = area_width // len(rays)
            color = pygame.Color((0, 0, 0)).lerp(colors[ray[3]], min(height/256, 1))
            rect = pygame.Rect(area_width + i*width, area_width//2-height//2, width, height)
            pygame.draw.rect(window, color, rect)
        pygame.display.flip()
    
    pygame.quit()
    exit()
    

    另请参阅 PyGameExamplesAndAnswers - Raycasting


    我知道您问的是 “...但我想知道是否有可能在不依赖任何其他依赖项的情况下制作非常基本的 3D 图形”。 无论如何,我将为您提供一些具有其他依赖项的附加选项。

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

    但是,您可以使用 Pygame 窗口创建 OpenGL Context 。您需要 pygame.OPENGL 在创建显示 Surface (请参阅 pygame.display.set_mode ):

    window = pg.display.set_mode((width, height), pygame.OPENGL | pygame.DOUBLEBUF)
    

    现代 OpenGL PyGame/PyOpenGL 示例:

    import pygame
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GL.shaders import *
    import ctypes
    import glm
    
    glsl_vert = """
    #version 330 core
    
    layout (location = 0) in vec3 a_pos;
    layout (location = 1) in vec4 a_col;
    
    out vec4 v_color;
    
    uniform mat4 u_proj; 
    uniform mat4 u_view; 
    uniform mat4 u_model; 
    
    void main()
    {
        v_color     = a_col;
        gl_Position = u_proj * u_view * u_model * vec4(a_pos.xyz, 1.0);
    }
    """
    
    glsl_frag = """
    #version 330 core
    
    out vec4 frag_color;
    in  vec4 v_color;
    
    void main()
    {
        frag_color = v_color;
    }
    """
    
    class Cube:
      
        def __init__(self):
            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)]
            edges = [(0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7)]
            surfaces = [(0,1,2,3), (5,4,7,6), (4,0,3,7),(1,5,6,2), (4,5,1,0), (3,2,6,7)]
            colors = [(1,0,0), (0,1,0), (0,0,1), (1,1,0), (1,0,1), (1,0.5,0)]
            line_color = [0, 0, 0]
    
            edge_attributes = []
            for e in edges:
                edge_attributes += v[e[0]]
                edge_attributes += line_color
                edge_attributes += v[e[1]]
                edge_attributes += line_color
    
            face_attributes = []
            for i, quad in enumerate(surfaces):
                for iv in quad:
                    face_attributes += v[iv]
                    face_attributes += colors[i]
    
            self.edge_vbo = glGenBuffers(1)
            glBindBuffer(GL_ARRAY_BUFFER, self.edge_vbo)
            glBufferData(GL_ARRAY_BUFFER, (GLfloat * len(edge_attributes))(*edge_attributes), GL_STATIC_DRAW)
            self.edge_vao = glGenVertexArrays(1)
            glBindVertexArray(self.edge_vao)
            glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*ctypes.sizeof(GLfloat), ctypes.c_void_p(0)) 
            glEnableVertexAttribArray(0) 
            glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*ctypes.sizeof(GLfloat), ctypes.c_void_p(3*ctypes.sizeof(GLfloat))) 
            glEnableVertexAttribArray(1) 
    
            self.face_vbos = glGenBuffers(1)
            glBindBuffer(GL_ARRAY_BUFFER, self.face_vbos)
            glBufferData(GL_ARRAY_BUFFER, (GLfloat * len(face_attributes))(*face_attributes), GL_STATIC_DRAW)
            self.face_vao = glGenVertexArrays(1)
            glBindVertexArray(self.face_vao)
            glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*ctypes.sizeof(GLfloat), ctypes.c_void_p(0)) 
            glEnableVertexAttribArray(0) 
            glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*ctypes.sizeof(GLfloat), ctypes.c_void_p(3*ctypes.sizeof(GLfloat))) 
            glEnableVertexAttribArray(1) 
    
        def draw(self):
            glEnable(GL_DEPTH_TEST)
    
            glLineWidth(5)
    
            glBindVertexArray(self.edge_vao)
            glDrawArrays(GL_LINES, 0, 12*2)
            glBindVertexArray(0)
    
            glEnable(GL_POLYGON_OFFSET_FILL)
            glPolygonOffset( 1.0, 1.0 )
    
            glBindVertexArray(self.face_vao)
            glDrawArrays(GL_QUADS, 0, 6*4)
            glBindVertexArray(0)
            
            glDisable(GL_POLYGON_OFFSET_FILL)
    
    def set_projection(w, h):
        return glm.perspective(glm.radians(45), w / h, 0.1, 50.0)
    
    pygame.init()
    window = pygame.display.set_mode((400, 300), pygame.DOUBLEBUF | pygame.OPENGL | pygame.RESIZABLE)
    clock = pygame.time.Clock()
    
    proj = set_projection(*window.get_size())
    view = glm.lookAt(glm.vec3(0, 0, 5), glm.vec3(0, 0, 0), glm.vec3(0, 1, 0))
    model = glm.mat4(1)
    cube = Cube()
    angle_x, angle_y = 0, 0
    
    program = compileProgram( 
        compileShader(glsl_vert, GL_VERTEX_SHADER),
        compileShader(glsl_frag, GL_FRAGMENT_SHADER))
    attrib = { a : glGetAttribLocation(program, a) for a in ['a_pos', 'a_col'] }
    print(attrib)
    uniform = { u : glGetUniformLocation(program, u) for u in ['u_model', 'u_view', 'u_proj'] }
    print(uniform)
    glUseProgram(program)
    
    run = True
    while run:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            elif event.type == pygame.VIDEORESIZE:
                glViewport(0, 0, event.w, event.h)
                proj = set_projection(event.w, event.h)
    
        model = glm.mat4(1)
        model = glm.rotate(model, glm.radians(angle_y), glm.vec3(0, 1, 0))
        model = glm.rotate(model, glm.radians(angle_x), glm.vec3(1, 0, 0))
       
        glUniformMatrix4fv(uniform['u_proj'], 1, GL_FALSE, glm.value_ptr(proj))
        glUniformMatrix4fv(uniform['u_view'], 1, GL_FALSE, glm.value_ptr(view))
        glUniformMatrix4fv(uniform['u_model'], 1, GL_FALSE, glm.value_ptr(model))
    
        angle_x += 1
        angle_y += 0.4
    
        glClearColor(0.5, 0.5, 0.5, 1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        cube.draw()    
        pygame.display.flip()
    
    pygame.quit()
    exit()
    

    传统 OpenGL PyGame/PyOpenGL 示例:

    import pygame
    from OpenGL.GL import *
    from OpenGL.GLU import *
    
    class Cube:
      
        def __init__(self):
            self.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)]
            self.edges = [(0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7)]
            self.surfaces = [(0,1,2,3), (5,4,7,6), (4,0,3,7),(1,5,6,2), (4,5,1,0), (3,2,6,7)]
            self.colors = [(1,0,0), (0,1,0), (0,0,1), (1,1,0), (1,0,1), (1,0.5,0)]
    
        def draw(self):
            glEnable(GL_DEPTH_TEST)
    
            glLineWidth(5)
            glColor3fv((0, 0, 0))
            glBegin(GL_LINES)
            for e in self.edges:
                glVertex3fv(self.v[e[0]])
                glVertex3fv(self.v[e[1]])
            glEnd()
    
            glEnable(GL_POLYGON_OFFSET_FILL)
            glPolygonOffset( 1.0, 1.0 )
    
            glBegin(GL_QUADS)
            for i, quad in enumerate(self.surfaces):
                glColor3fv(self.colors[i])
                for iv in quad:
                    glVertex3fv(self.v[iv])
            glEnd()
    
            glDisable(GL_POLYGON_OFFSET_FILL)
    
    def set_projection(w, h):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(45, w / h, 0.1, 50.0)
        glMatrixMode(GL_MODELVIEW)
    
    def screenshot(display_surface, filename):
        size = display_surface.get_size()
        buffer = glReadPixels(0, 0, *size, GL_RGBA, GL_UNSIGNED_BYTE)
        screen_surf = pygame.image.fromstring(buffer, size, "RGBA")
        pygame.image.save(screen_surf, filename)
    
    pygame.init()
    window = pygame.display.set_mode((400, 300), pygame.DOUBLEBUF | pygame.OPENGL | pygame.RESIZABLE)
    clock = pygame.time.Clock()
    
    set_projection(*window.get_size())
    cube = Cube()
    angle_x, angle_y = 0, 0
    
    run = True
    while run:
        clock.tick(60)
        take_screenshot = False
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            elif event.type == pygame.VIDEORESIZE:
                glViewport(0, 0, event.w, event.h)
                set_projection(event.w, event.h)
            elif event.type == pygame.KEYDOWN:
                take_screenshot = True
    
        glLoadIdentity()
        glTranslatef(0, 0, -5)
        glRotatef(angle_y, 0, 1, 0)
        glRotatef(angle_x, 1, 0, 0)
        angle_x += 1
        angle_y += 0.4
    
        glClearColor(0.5, 0.5, 0.5, 1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        cube.draw()   
        if take_screenshot: 
            screenshot(window, "cube.png")
        pygame.display.flip()
        
    pygame.quit()
    exit()
    
  • Pygame 最初并不是用来做 3D 的,但有一种方法可以用任何 2D 图形库来做 3D。您所需要的只是以下函数,它将 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 设计的库。

  • 它不支持,但结合 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()
    

    enter image description here

  • iBug 1月前 0 只看Ta
    引用 12

    问题明确地问道,“我想知道是否有可能在不依赖任何其他依赖项的情况下完成非常基本的 3d 图形。” PyOpenGL 是一个额外的库和一个额外的依赖项。

  • 你看到的 3D 图像实际上是 2D 游戏。毕竟,你正在观看的是你的屏幕,而屏幕(通常 ;) 是 2D 的。虚拟世界(3D 的)被投射到平面上,然后显示在你的屏幕上。然后我们的大脑将 2D 图像转换为 3D 图像(就像它们对我们眼睛的图像所做的那样),使其看起来像 3D 的。

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

    有一个教程可以让你开始使用 3D 程序(使用 pygame),就是 这个 .

  • 你可以这样做:

    def convert_2d(x, y, z, horizon):
        d = 1 - (z/horizon)
        return x*d, y*d
    def draw_list_of_points(lst):
        '''Assume that lst is a list of 3 dimentionnal points like [(0, 0, 0), (1, 6, 2)...
        Let's take 200 for the horizon, it can give us a pretty clean 3D''' 
        for x, y, z in lst:
            pygame.draw.circle(screen, color, convert_2d(x, y, z, 200), 1)
    
    

    但是速度不是很快。如果你想要更快,可以尝试用 C++/SDL2 或 C 来实现。Pygame 不太适合 3D 图形。

  • 引用 15

    为 PyGame 制作 3D 驱动程序很容易。PyGame 有一些用于 3D 游戏开发的资产。我现在正在使用 PyGame 开发 Py3D 驱动程序。完成后,我会向您显示下载 Py3D 的链接。我尝试使用 PyGame 制作 3D 游戏,但我只需要 PyGame 的小插件。您认为必须使用 SDL、PyOpenGL、OpenGL、PyQt5、Tkinter 是错误的。它们都不适合制作 3D 游戏。OpenGL 和 PyOpenGL 或 Panda3D 非常难学。我用这些驱动程序制作的所有游戏都很糟糕。PyQt5 和 Tkinter 不是用于制作游戏的驱动程序,但它们有插件。不要尝试在这些驱动程序上制作任何游戏。所有需要使用数学模块的驱动程序都很难。您可以轻松地为它们制作小插件,我认为每个人都可以在 1-2 周内为 PyGame 制作驱动程序。

  • Eli 1月前 0 只看Ta
    引用 16

    如果您想在制作游戏时坚持使用类似 Python 的语言,Godot 是一个不错的选择,它同时支持 2D 和 3D,拥有庞大的社区和大量教程。它的自定义脚本语言 (gdscript) 有一些细微的差别,但总体而言基本相同。它还支持 c# 和 c++,在游戏开发方面具有更多功能。

  • Pygame 只是一个用于更改像素颜色的库(以及一些用于编程游戏的其他有用的东西)。您可以通过将图像传输到屏幕上或直接设置像素颜色来实现这一点。

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

    由于这需要巨大的处理能力,这不仅会运行缓慢,而且还需要您编写一个庞大的 3D 渲染/光栅化引擎。而且由于需要解释 Python,因此速度会更慢。正确的方法是使用 (Py)opengl 在 GPU 上运行此过程。

    所以,从技术上讲,仅使用 pygame 实现 3D 是可行的,但绝对不推荐。我建议你学习 Panda3D 或类似的 3D 引擎。

  • 简单:只需绘制一堆多边形,如下:

    import pygame
    screen = pygame.display.set_mode((100, 100))
    While True:
       screen.fill((0, 0, 0))
       Pos = [(10, 10), (20, 10), (20, 20), (10, 20)]
       # first side (the front) in red
       pygame.draw.polygon(screen, (225, 0, 0), Pos)
       # outline in white
       pygame.draw.lines(screen, (225, 225, 225), Pos)
       # Second side (the back) in blue
       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(screen, (0, 0, 225), Pos2)
       pygame.draw.lines(screen, (225, 225, 225), Pos2)
       # Third side (the left but just 2 lines(not really)) in green 
       Pos3 = [Pos[0], Pos2[0], Pos2[3], Pos[3]]
       pygame.draw.polygon(screen, (0, 225, 0), Pos3)
       pygame.draw.lines(screen, (225, 225, 225), Pos3)
       # Fourth side (the right) in purple
       Pos4 = [Pos[1], Pos2[1], Pos2[2], Pos[2]]
       pygame.draw.polygon(screen, (225, 0, 225), Pos4)
       pygame.draw.lines(screen, (225, 225, 225), Pos4)
       pygame.display.flip()
    

    &有一个简单的立方体&我很快会提供完整代码的链接,以便能够旋转立方体并调整其大小

    这应该能给你与使用 OpenGL 获得的结果相当的结果

  • 这是我仅使用 Pygame 和 Numpy 而没有使用 OpenGL 和一些基本的阴影所完成的。

    enter image description here

    您可以在 PyGame 中实现 3D,但可能不是最高效和最快的。

返回
作者最近主题: