官术网_书友最值得收藏!

Loading data asynchronously

Panda3D really makes it very easy to load and use assets like models, actors, textures, and sounds. But there is a problem with the default behavior of the asset loader—it blocks the execution of the engine.

This is not a problem if all data is loaded before the player is allowed to see the game world, but if models and other assets are to be loaded while the game is running, we are facing a serious problem because the frame rate will drop dramatically for a moment. This will cause game execution to stop for a short moment in a sudden and unpredictable way that breaks gameplay.

To avoid getting into such problems, Panda3D offers the ability to load data through a background thread. This is a very useful feature if game assets are loaded on the fly, such as the popular use case with seamless streaming in game worlds. It is also a great way to reduce initial loading times. The main level geometry and everything visible from the starting position is loaded before the player enters the world and the rest of it is loaded afterwards, often depending on the position in the game world.

Getting ready

For this recipe you will need to set up the basic framework described in Setting up the game structure.

How to do it...

Follow these steps to create a sample application that demonstrates asynchronous data loading:

  1. Add the following code to Application.py:
    from direct.showbase.ShowBase import ShowBase
    from direct.actor.Actor import Actor
    from panda3d.core import Vec3
    
    class Application(ShowBase):
        def __init__(self):
            ShowBase.__init__(self)
            self.cam.setPos(0, -30, 6)
            taskMgr.doMethodLater(3, self.load, "load", extraArgs = ["teapot", Vec3(-5, 0, 0), self.modelLoaded])
            taskMgr.doMethodLater(5, self.load, "load", extraArgs = ["panda", Vec3(5, 0, 0), self.actorLoaded])
    
        def load(self, name, pos, cb):
            loader.loadModel(name, callback = cb, extraArgs = [pos])
    
        def modelLoaded(self, model, pos):
            model.reparentTo(render)
            model.setPos(pos)
    
        def actorLoaded(self, model, pos):
            self.panda = Actor(model, {"walk": "panda-walk"})
            self.panda.reparentTo(render)
            self.panda.setPos(pos)
            self.panda.loop("walk")
  2. Press F6 to run the application. You will see a delay before the teapot and the panda appear in the window.

How it works...

The previous code enqueues calls to the load() method using doMethodLater() so you can see the objects pop up as soon as they are loaded. The list passed to the extraArgs parameter will be used as parameters for the call to load().

The call to loadModel() within the load method is very important, because instead of just passing the name of the model to load, you also set the callback parameter to one of the modelLoaded() and actorLoaded() methods, depending on what the cb parameter of load() contains.

As soon as a call to loadModel() uses the callback parameter, the request to load the data is handed off to a background thread. When the required asset has finished loading, the callback function is called and the loaded asset is passed as the first parameter, as you can see in the modelLoaded() and actorLoaded() methods.

主站蜘蛛池模板: 兴山县| 石泉县| 大英县| 行唐县| 乳山市| 昂仁县| 抚远县| 莒南县| 湘潭市| 钟山县| 玉林市| 南溪县| 靖边县| 清原| 宁河县| 法库县| 彩票| 景洪市| 红桥区| 绍兴市| 东阳市| 长治县| 突泉县| 哈尔滨市| 信丰县| 建昌县| 堆龙德庆县| 托克逊县| 新竹市| 砚山县| 饶平县| 秀山| 都兰县| 西华县| 安图县| 开阳县| 霞浦县| 敦煌市| 彭泽县| 年辖:市辖区| 吴旗县|