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):
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.