Panda3D学习 (2):机器人示例程序

第二个学习的例程,选了机器人的程序,因为感觉可能和实习比较相关一些。。

1.序列和并行

Sequences play intervals one after the other, effectively a “do in order” command.

序列在小行星例程中也碰到过

Parallels are a “do together,” playing all intervals at the same time. 

mySequence = Sequence(myInterval1,…,myIntervaln, name="Sequence Name")
myParallel = Parallel(myInterval1,…,myIntervaln, name="Parallel Name")




2.姿态角

例程 :camera.setPosHpr(14.5, -15.4, 14, 45, -14, 0)

Pos指的是x,y,z三轴,Hpr指的是姿态角(绕x,y,z轴旋转的角度) (heading,pitch,roll)


3.self.setupLights()

顾名思义,开启灯光,实测了一下差距是挺大的

    def setupLights(self):
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.8, .8, .75, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(LVector3(0, 0, -2.5))
        directionalLight.setColor((0.9, 0.8, 0.9, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

4.(疑问) camera 和 render

在小行星例程中,obj.reparentTo(camera), 当我将其改为obj.reparentTo(render)的时候似乎没有任何问题。

本例程中,将render改为camera就不行了。

我的理解下是render是静止的场景图和camera是相机,决定了所要看到的场景图的视角 (和main page上的hellowworld程序类似),但这样如何解释小行星例程中用camera也可以呢?

# Every object uses the plane model and is parented to the camera

# so that it faces the screen.

不是很懂

5. Actor演员类

这里我还没看到手册上关于Actor的详细介绍,但我觉得这个例程的备注已经非常清晰:

# Models that use skeletal animation are known as Actors instead of models
        # Instead of just one file, the have one file for the main model, and an
        # additional file for each playable animation.
        # They are loaded using Actor.Actor instead of loader.LoadModel.
        # The constructor takes the location of the main object as with a normal model
        # and a dictionary (A fancy python structure that is like a lookup table)
        # that contains names for animations, and paths to the appropriate
        # files
        self.robot1 = Actor.Actor('models/robot',
                                  {'leftPunch': 'models/robot_left_punch',
                                   'rightPunch': 'models/robot_right_punch',
                                   'headUp': 'models/robot_head_up',

                                   'headDown': 'models/robot_head_down'})

# Actors need to be positioned and parented like normal objects
        self.robot1.setPosHprScale(-1, -2.5, 4, 45, 0, 0, 1.25, 1.25, 1.25)
        self.robot1.reparentTo(render)

主页的介绍如下:

Loading each animation requires a tuple: the name one is giving the animation and the path to the animation. This entire process can be shortened to a single command:

nodePath = Actor('Model Path', {
  'Animation Name 1':'Animation Path 1',
  'Animation Name 2':'Animation Path 2',
})

6. Actor添加动作

     # Now we define how the animated models will move. Animations are played
        # through special intervals. In this case we use actor intervals in a
        # sequence to play the part of the punch animation where the arm extends,
        # call a function to check if the punch landed, and then play the part of the
        # animation where the arm retracts


        # Punch sequence for robot 1's left arm
        self.robot1.punchLeft = Sequence(
            # Interval for the outstreched animation
            self.robot1.actorInterval('leftPunch', startFrame=1, endFrame=10),
            # Function to check if the punch was successful
            Func(self.checkPunch, 2),
            # Interval for the retract animation

            self.robot1.actorInterval('leftPunch', startFrame=11, endFrame=32))

# Now that we have defined the motion, we can define our key input.
        # Each fist is bound to a key. When a key is pressed, self.tryPunch checks to
        # make sure that the both robots have their heads down, and if they do it
        # plays the given interval
        self.accept('escape', sys.exit)
        self.accept('a', self.tryPunch, [self.robot1.punchLeft])
        self.accept('s', self.tryPunch, [self.robot1.punchRight])
        self.accept('k', self.tryPunch, [self.robot2.punchLeft])

        self.accept('l', self.tryPunch, [self.robot2.punchRight])

这两段分别定义了Actoer的动作和触发条件,也是本例程的核心内容。具体语法需要先去看一下主页手册的内容。


7. 动画控制

查询了手册之后,发现了这样几种控制方式:

首先对Actor的加载如5中不变:

第一种,不是例程中用到的,但更简单一些

actor.play('Animation Name')
actor.loop('Animation Name')

actor.stop()

参数即动作名称,三个函数的名称也很显然对应了其功能

actor.pose('Animation Name', FrameNumber)

这个函数pose的介绍是保持特定的一帧即第二个参数,有点像暂停的感觉?

actor.pose('Animation Name', 30)

actor.loop('Animation Name', restart = 0, fromFrame = 24, toFrame = 36)

也可以控制动画的具体播放帧

还有一个叫做AnimControl是一个可以控制某个动画的类。用法如下:很像例程中的方法了

myAnimControl=actor.getAnimControl('Animation Name') #get the AnimControl
 
myAnimControl.isPlaying() #returns a boolean whether the animation is playing or not
myAnimControl.getFrame() #returns the current frame number
myAnimControl #returns the speed of the animation, in frames per second
myAnimControl.getFullFframe() #returns a floating-point frame number exceeding the framecount. Not recommended.
myAnimControl.getFullFrame() #returns an integer frame number exceeding the framecount. Not recommended.
myAnimControl.getNextFrame() #returns the number of the next frame on the queue.
myAnimControl.getNumFrames() #returns the total number of frames
myAnimControl.getPlayRate() #returns the playrate. explained further below
myAnimControl.loop() #starts playing the animation in a loop
myAnimControl.play() #starts playing the animation
myAnimControl.pose(frame) #poses at frame frame
myAnimControl.setPlayRate(rate) #sets the playrate. explained further below

myAnimControl.stop() #stops the animation


第二种就是例程中用的,属于Intervals这一大块

我感觉是建立动画interval,然后作为Actor的属性可以被调用,使用下面的语句进行播放:

interval.start()
interval.start(startT, endT, playRate)
interval.loop()
interval.loop(startT, endT, playRate)
interval.finish()
interval.pause()
interval.resume()

还有一些常用的语法,都比较简单,详见手册就可以了

有一点似乎 例程中将Sequence圈起来的多个interval可以当作一个interval来start,似乎表明可以通过这种方式来组合动画

猜你喜欢

转载自blog.csdn.net/zanbaixi2128/article/details/80779299
今日推荐