Camera That Floats Around A Player

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Lomion047
Posts: 1
Joined: Fri Sep 02, 2011 5:44 am

Camera That Floats Around A Player

Post by Lomion047 »

I haven't read too much about camera control in the forums except for using the built in FPS style camera. I also like different entities in my code to be very object oriented and require little to no maintenance, but be very versatile. To that end, I wrote this camera class:

Code: Select all

#include <irrlicht.h>
 
#define PI 3.14159265
#define CAM_MOVEMENT_SPEED 1
#define CAM_MIN_DISTANCE 50
#define CAM_MAX_DISTANCE 200
using namespace irr;
 
class cam
{
public:
        scene::ISceneManager* smgr;
        scene::ICameraSceneNode* camera;
        float angle;
        float angleMod;
        float distance;
        float height;
        void update()
        {
                // Keep that camera between 50-200 units from the target
                if (distance < CAM_MIN_DISTANCE) distance = CAM_MIN_DISTANCE;
                else if (distance > CAM_MAX_DISTANCE) distance = CAM_MAX_DISTANCE;
 
                // Reset the angle if they go past 0 or 360 degrees rotation
                // This isn't really necessary, but will prevent any issues with
                // extremely high/low numbers if the player moves the camera in
                // circles over and over again.
                if (angle > 360) angle -= 360;
                else if (angle < 0) angle += 360;
 
                // Get the target data and translate the camera's position to
                // continue orbitting around it
                core::vector3df targ = camera->getTarget();
                float x = sin((angle + angleMod) * PI / 180) * distance;
                x += targ.X;
                float y = targ.Y + height;
                float z = cos((angle + angleMod) * PI / 180) * distance;
                z += targ.Z;
                camera->setPosition(core::vector3df(x, y, z));
        }
        void zoom(core::stringw which)
        {
                if (which == "in") distance -= CAM_MOVEMENT_SPEED;
                else if (which == "out") distance += CAM_MOVEMENT_SPEED;
                return;
        }
        void move(core::stringw which)
        {
                if (which == "left") angle -= CAM_MOVEMENT_SPEED;
                else if (which == "right") angle += CAM_MOVEMENT_SPEED;
        }
        // Initialize the camera
        cam::cam(scene::ISceneManager* scene)
        {
                smgr = scene;
                angle = 0;
                angleMod = 0;
                distance = 150.0;
                height = 50.0;
                camera = smgr->addCameraSceneNode();
        }
};
I wrote the code so that you can add it as a separate .h file to any project. To include it, just add #include "cam.h" (or whatever you call it) to your main.cpp. To initialize it, you only have to pass it your scene manager like so:

Code: Select all

cam camera = cam(smgr);
The camera will orbit around it's "target" infinitely using basic trig. All you have to do to orbit is call one of the following:

Code: Select all

camera.move("left");
camera.move("right");
You can also "zoom" in or out from your target by calling:

Code: Select all

camera.zoom("in");
camera.zoom("out");
The only other thing you have to do in your main code is tell the camera what it's target is. I also created my own class for my player data, so for me it'll go like this:

Code: Select all

camera.camera->setTarget(player.node->getPosition());
Lastly, you have to tell the camera to update in your main loop. The camera updates it's own position, rotation, and everything by calling

Code: Select all

camera.update();
That's all for using it in your game, but there's a few things you can change to tweak it pretty easily. In the defines, you can change the minimum or maximum distance the camera will be from your target, as well as the speed at which the camera will orbit the target. The camera will always float at the same height relative to it's target, so you'll notice the camera pan up and down slightly as you zoom in and out. I left it this way to leave out the extra trig functions, and thereby save a little bit of processing time (since it will run them every loop). It certainly shouldn't make or break your game if you wanted to add in height control the update function. Also, the height isn't a constant, so you can update it from outside of this class if you want to.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: Camera That Floats Around A Player

Post by christianclavet »

Thanks for posting that code. I'm sure it could make a nice RPG camera...
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Camera That Floats Around A Player

Post by Mel »

Have you tried to smooth the motions? Your camera right now will look too abrupt when it moves because you update the position absolutely. If instead of updating the position directly, you blend between the previous position and the new one like:

Code: Select all

position = position*0.9 + newPosition*0.1;
the motion becomes very fluid.

But looks nice. Good job :)
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Post Reply