PyGame 能做 3d 吗?

2025-03-04 08:24:00
admin
原创
88
摘要:问题描述:我似乎在任何地方都找不到这个问题的答案。我知道你必须使用 PyOpenGL 或类似的东西来做 OpenGL 的事情,但我想知道是否有可能在不依赖任何其他依赖项的情况下完成非常基本的 3D 图形。解决方案 1:不,Pygame 是 SDL 的包装器,SDL 是一个 2D API。Pygame 不提供任...

问题描述:

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


解决方案 1:

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

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

解决方案 2:

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

解决方案 3:

在没有其他依赖项帮助的情况下,Pygame 中的 3D 渲染很难实现,并且性能不佳。Pygame 不提供任何绘制 3D 形状、网格甚至透视和照明的功能。

如果您想使用 Pygame 绘制 3D 场景,则需要使用矢量算法计算顶点并使用多边形将几何图形拼接在一起。Pygame绕轴旋转立方体

的答案示例:

IT科技

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

尽管如此,使用 2.5-D 方法可以取得不错的效果。请参阅如何修复射线投射器中的墙体扭曲?的答案:

IT科技

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或ModernGL。

但是,您可以使用 Pygame 窗口创建OpenGL 上下文pygame.OPENGL。您需要在创建显示表面时设置标志(请参阅pygame.display.set_mode):

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

现代 OpenGL PyGame/PyOpenGL 示例:

IT科技

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 示例:

IT科技

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

解决方案 4:

你可以只用 pygame 来做伪 3d 游戏(比如“毁灭战士”):

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

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

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

解决方案 5:

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 设计的库。

解决方案 6:

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

在此处输入图片描述

解决方案 7:

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

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

这是一个可以引导您使用 3D 程序(使用 pygame)的教程。

解决方案 8:

你可以这样做:

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 图形。

解决方案 9:

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

解决方案 10:

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

解决方案 11:

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

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

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

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

解决方案 12:

很简单:只需绘制一堆多边形,如下所示:

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 获得的结果相当的结果

解决方案 13:

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

在此处输入图片描述

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

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3878  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2714  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   47  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   48  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   48  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用