我如何在pygame中随机生成立方体?

问题描述 投票:0回答:2

我需要代码 如何仅使用 pygame 创建随机生成的 3dcube 从屏幕顶部创建,然后从屏幕顶部落到屏幕底部 请帮我 使用 python pygame

python python-3.x pygame pycharm
2个回答
0
投票

正如 @The_spider 提到的,pygame 是一个 2D 游戏引擎。它无法加载 3D 文件或执行任何 3D 操作。一些推荐的模块是 Panda3d 和 Ursina(这是 Panda3d 的简化版本)通过 pip 安装它们。 如果你确实需要使用 pygame,则必须保存立方体各个角度的图像,并使用极其复杂的算法将其 Blit 到屏幕上。而且,速度会非常慢。因此,使用 python 3D 游戏引擎。


0
投票

一年前我回答过这个问题,说在 Pygame 中不可能显示 3D 对象。我做了更多的研究并创建了一个解决方案。您可以使用 Panda3D 或 Ursina 处理 3D 对象(您的立方体),然后将 3D 引擎的输出逐帧显示到 Pygame 窗口中。以下代码是有关如何使用 Panda3D 或 Ursina 渲染 3D 对象然后将它们显示到 Pygame 窗口中的示例。

Panda3D 实现

from PIL.Image import frombytes, merge
import pygame
from direct.showbase.ShowBase import ShowBase
from panda3d.core import Spotlight


class MyApp(ShowBase):
    def __init__(self, screen_size = 50):
        ShowBase.__init__(self, windowType='offscreen')

        # Spotlight
        self.light = Spotlight('light')
        self.lightNP = self.render.attachNewNode(self.light)
        self.lightNP.setPos(0, 84, 75)
        self.lightNP.lookAt(0, 42, 0)
        self.render.setLight(self.lightNP)

        # Load the built-in RGB Cube.
        self.environ = self.loader.loadModel("models/misc/rgbCube")

        # Reparent the model to render.
        self.environ.reparentTo(self.render)

        # Apply scale and position transforms on the model.
        self.environ.setScale(10, 10, 10)
        self.environ.setPos(0, 42, 0)



    def get_camera_image(self):
        #Get image of panda3d offscreen buffer
        dr = self.camNode.getDisplayRegion(0)
        tex = dr.getScreenshot()
        data = tex.getRamImage().getData()
        sx = tex.getXSize()
        sy = tex.getYSize()

        #Convert Image to Pygame Image
        b,g,r,a = frombytes("RGBA", (sx, sy), data).split()
        pyGmImg = pygame.image.fromstring(merge("RGBA", (r, g, b, a)).tobytes(), (sx, sy), "RGBA", True)
        return pyGmImg

    def step(self):
        # Move the Cube
        self.environ.setHpr(((self.environ.getH() + globalClock.getDt() * 100),
                             (self.environ.getH() + globalClock.getDt() * 100),
                             (self.environ.getH() + globalClock.getDt() * 100)))
        #Render Image
        self.graphicsEngine.renderFrame()
        image = self.get_camera_image()
        return image


def main():
    #Initialise Pygame and Create Window
    pygame.init()
    PyWin = pygame.display.set_mode((800, 600))

    #Initialise Panda3d Application
    app = MyApp()

    running = True

    while running:
        #Make Panda3D Render Image
        image = app.step()

        #Display Image into Pygame Window
        PyWin.fill(0)
        PyWin.blit(image, (0, 0))

        #Update the Display
        pygame.display.flip()

        #Check for Quit event in Pygame
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                
                #Quit Pygame and Panda3D
                pygame.quit()
                app.destroy()
                running = False

if __name__ == '__main__':
    main()

Ursina 实施

from ursina import *
import pygame
from PIL.Image import frombytes, merge

#Initialise Pygame
pygame.init()

#Create a Pygame Window
PyWin = pygame.display.set_mode((2304, 1440))

#Initialise Ursina App
app = Ursina(window_type='offscreen')    # Initialise your Ursina app

#Create a Cube
cube = Entity(model='cube', color=color.orange, scale=(2,2,2))

def update():
    #Rotate Cube and change Colour
    cube.rotation_y += time.dt * 100
    cube.rotation_x += time.dt * 100
    cube.rotation_z += time.dt * 100
    cube.color = rgb(int(cube.rotation_y - 200) % 255, int(cube.rotation_y - 100) % 255, int(cube.rotation_y) % 255)

    # Get image of ursina offscreen buffer
    dr = app.camNode.getDisplayRegion(0)
    tex = dr.getScreenshot()
    data = tex.getRamImage().getData()
    sx=tex.getXSize()
    sy=tex.getYSize()
    b,g,r,a = frombytes("RGBA",(sx,sy),data).split()

    # Convert Image to Pygame Image
    pyGmImg= pygame.image.fromstring(merge("RGBA",(r,g,b,a)).tobytes(),(sx,sy),"RGBA",True)

    # Display Image into Pygame Window
    PyWin.blit(pyGmImg, (0,0))

    # Update the Display
    pygame.display.flip()

#Run the Usina App (Use Ctrl+C to quit)
app.run()

注意:

  1. 如果您对
    frombytes()
    tobytes()
    有疑问,请尝试更改 其折旧
    fromstring()
    tostring()
    。但是离开
    pygame.image.fromstring
    不变
    。如果您是,这可能需要 使用旧版本的 Pillow。这适用于所示的两个程序 上面。
  2. 在 Ursina 中,不要从以下位置导入
    FirstPersonController
    ursina.prefabs.first_person_controller
    ,Ursina 的一些 功能在屏幕外缓冲区中不起作用。

我留下“随机生成的 3dcube”和“从屏幕顶部创建,然后从屏幕顶部落到屏幕底部”部分,让您自行了解如何使用您选择的游戏引擎。请记住,来自 Panda3D 和 Ursina 的用户输入(光标单击、光标位置、键盘按下)将不起作用,因此请使用 Pygame 获取用户输入。祝你的游戏创作顺利!

© www.soinside.com 2019 - 2024. All rights reserved.