0
\$\begingroup\$

In order to learn PyOpenGL and test out an engine I am developing, I am trying to write a 3D asteroids flying space shooter game. Currently, I am implementing the camera using a "look at" function positioned right behind the player's ship. The player is able to control the yaw and pitch with the left+right and up+down arrow keys respectively. The results look like this (forgive the placeholder art):

Screenshot of my 3D asteroids game illustrating the current camera system

And here is the code snippet in my Player class that implements that:

from pyorama.entity import Entity
from pyorama.math3d.vec3 import Vec3
from pyorama.math3d.mat4 import Mat4
import math

class Player(Entity):

    def __init__(self, model, camera):
        self.model = model
        self.center = self.model.mesh.compute_bounding_sphere().center
        self.model.transform = self.model.transform.translate(-self.center)
        self.camera = camera
        self.key_down_status = {"Left": False, "Right": False, "Up": False, "Down": False}
        super(Player, self).__init__()

    def update(self):
        messages = super(Player, self).update()
        for message in messages:
            if message.event_type == "key_down":
                key = message.data["key_name"]
                if key in self.key_down_status.keys():
                    self.key_down_status[key] = True
            if message.event_type == "key_up":
                key = message.data["key_name"]
                if key in self.key_down_status.keys():
                    self.key_down_status[key] = False

        self.model.transform = self.model.transform.translate(self.center)
        if self.key_down_status["Up"]:
            self.model.transform = self.model.transform.rotate_x(-0.01)
        if self.key_down_status["Down"]:
            self.model.transform = self.model.transform.rotate_x(0.01)
        if self.key_down_status["Left"]:
            self.model.transform = self.model.transform.rotate_y(0.01)
        if self.key_down_status["Right"]:
            self.model.transform = self.model.transform.rotate_y(-0.01)
        self.model.transform = self.model.transform.translate(-self.center)
        self.model.transform = self.model.transform.translate(Vec3(0, 0, 0.1))

        right = self.model.transform.data[0:3]
        up = Vec3(*self.model.transform.data[4:7])
        forward = Vec3(*self.model.transform.data[8:11])
        position = Vec3(*self.model.transform.data[12:15])

        temp = self.model.transform
        self.model.transform = self.model.transform.translate(+self.center)
        right = self.model.transform.data[0:3]
        up = Vec3(*self.model.transform.data[4:7])
        forward = Vec3(*self.model.transform.data[8:11])
        position = Vec3(*self.model.transform.data[12:15])

        self.camera.view = Mat4.look_at(position - 20 * forward, position, up)
        self.model.transform = temp

As you can see, the ship stays perfectly still behind and the world rotates around. As a result, it looks very unnatural, as if a 2D ship sprite was simply glued onto the screen!

So my question is, how are third-person cameras in flying games typically implemented? What would a keyboard+mouse control scheme look like that controls yaw, pitch, roll, banking, acceleration/deceleration, etc? Would the camera controls for the camera be separated from moving the ship? Any help would be greatly appreciated.

\$\endgroup\$
1
\$\begingroup\$

The camera control is usually semi-separated from the ship's rotation. Instead of making the camera have the same angles as the ship, the camera should try getting closer to the ship's angles.

In your update method get the difference between the ship's angles and the camera's angles, multiply it with a value between 1 and 0 (The greater the value is, the faster the camera will follow the ship) then add it to the camera's angles.

\$\endgroup\$
  • \$\begingroup\$ Haven't had the time to try out your answer yet but thanks, it seems pretty intuitive now! I will update the question with the working result. \$\endgroup\$ – CodeSurgeon Jan 17 '17 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.