Camera confusion

I’m new to panda3d and I’m messing around with the tutorials and sample programs.

I want to modify the Asteroids program so that the camera follows overhead the player’s ship. So no matter how the ship moves, the camera is always directly overhead of it.

I tried to take code from https://www.panda3d.org/manual/index.php/Controlling_the_Camera and put it into the asteroids code https://www.panda3d.org/manual/index.php/Sample_Programs:_Asteroids, but nothing seems to work.

Can someone give me the minimal set of changes to the Asteroids sample that would make this work along with some explanation?

Any help is greatly appreciated.

Here is what I have tried so far:
At the end of the updateShip method I have tried every permutation of the following:

base.camera.setX(self.ship.getX())
base.camera.setZ(self.ship.getZ())
base.camera.lookAt(self.ship)
base.camera.setPos(self.ship.getX(), base.camera.getY(), self.ship.getZ())

At the start of the file I imported ShowBase

from direct.showbase.ShowBase import ShowBase

And I made World an instance of ShowBase instead of DirectObject

#class World(DirectObject):
class World(ShowBase):

I’ve tried the code with and without a call to ShowBase’s init method:

  def __init__(self):
    #ShowBase.__init__(self)

When I do call ShowBase.init(self), I get this error:

“StandardError: Attempt to spawn multiple ShowBase instances!”

I assume that error stems from ShowBase being some kind of global object that was already initialized?

You won’t get very far doing things that way (copy/paste programming) and I don’t mean that as an insult, just that it’s not very effective. You’ll likely learn more starting with moving one node around and expanding from there rather starting with a more extensive (unmalleable) sample and trying to reshape it.

That said, I won’t leave you hanging. If you look in the loadObject function you will see that everything is parented to the camera. So moving the camera has no visible effect because everything else moves along with it. The following changes will get you started. First change the line under loadObject that says obj.reparentTo(camera) to:

obj.reparentTo(render)

Then go down to the World.init function and under the line that says self.ship = loadObject(“ship”) add the following two lines:

camera.reparentTo(self.ship)
camera.setPos(0,-55,0)

Now the camera follows the ship because it is parented to it. The setPos line just moves it back far enough to see the field. At the default (0,0,0) it is right in the middle of the ship and nothing is visible.

Yes, importing direct.directbase.DirectStart is a kind of “shortcut” which creates a global ShowBase instance. You can also do it the way you described, but you can’t do both.

Thank you for a clear and polite response. I appreciate it greatly.

Yeah, I should know better than copy paste programming :blush: