|
2d camera |
tinyBigGAMES
Member #17,458
February 2020
|
Hi all, I have people requesting a 2d camera system in my game framework, which is powered by allegro. I was wondering if you could give me advance on implementing this and/or point me to some resources, etc. camera should have a target, offset, rotation and zoom. I'm thinking I should be able to implement these using transformations, correct? Thanks Jarrod Jarrod Davis |
Chris Katko
Member #1,881
January 2002
|
I have a viewport class that holds the information about the viewport. struct viewport { float x, y; //viewport starting x and y on the screen (e.g. x is larger if you're starting for a right-side of a split screen viewport) float ox, oy; //offset x/y (this is the movement of the 'camera') float w, h; // width / height of viewport } when you draw you do this: al_draw_bitmap(x + v.x - v.ox, y + v.y - v.oy, ...); If the ox, and oy move up, the "camera" is scrolling down and to the right. So we then subtract that value from the drawn sprite routines. -----sig: |
DanielH
Member #934
January 2001
|
Same as above. Also, you can move the camera every time player moves. This keeps the player always in the center. I like a buffer. I'll create an imaginary rectangle slightly smaller than viewport. Maybe 100 on each side. I'll only move the camera when the player goes outside of the smaller rectangle. This allows free movement inside the rectangle. When you draw your sprites, as stated before, adjust the xy amount by the camera xy. |
tinyBigGAMES
Member #17,458
February 2020
|
Sweet! I see. So, if I defined a huge virtual world, say 20000x20000, then moved the camera around in this world, the objects positions are normalized to the camera position, then rendered. What about rotation and zooming? I was thinking about something like: camera2d_start(cam) And you do not have to manually update each object, allegro will take care of it. Plus you get your zoom and rotation too. Is this not possible? Jarrod Davis |
Chris Katko
Member #1,881
January 2002
|
Note: you don't have to update objects with changing camera position. You just add the camera position when you draw at the end. Rotation and zoom can be done different ways depending on your game. You can zoom "out" (and in) by drawing to a larger bitmap, and then scaling it down and rotating it when drawing it to the screen. -----sig: |
Mark Oates
Member #1,146
March 2001
|
I got AllegroFlare::Placement2D for ya: Placement2D is typically used for positioning objects on a screen (sprites), but it can also work as a camera. It has the properties position, size, align, scale, and anchor. All of these are vec2d(x, y). It also has rotation (float) and flip, also vec2d(x, y). You would typically position objects (sprites, text) by: Placement2D place; place.start_transform(); // do your drawing here, as if the orientation is 0, 0 place.restore_transform(); For a Camera, rather than using start_transform(), you would use start_reverse_transform(), and have these calls wrap around the objects when they are being drawn in the scene. So, Placement2D camera; camera.start_reverse_transform(); // draw all your entities here using their usual world coordinates camera.restore_transform(); By default, Placement2D has an alignment of (0.5, 0.5), so your camera will zoom in and out, and be pointed such that the position of the camera (position.x, position.y) is at the center of the screen. So, if your character sprite is at (300, 200), and your camera is at position (300, 200), then the character will be at the center of the screen. And, when you zoom in/out, the character will still be at the center. Note that you can nest multiple Placement2Ds inside each other and they will retain the transform from the previous element. Placement2D camera; camera.start_reverse_transform(); Placement2D sprite_placement; sprite_placement.start_transform(); al_draw_bitmap(bmp, 0, 0, 0); sprite_placement.restore_transform(); Placement2D sprite_placement2; sprite_placement2.start_transform(); al_draw_bitmap(bmp2, 0, 0, 0); sprite_placement2.restore_transform(); camera.restore_transform();
-- |
tinyBigGAMES
Member #17,458
February 2020
|
Thank you, kind sir, this is what I am after. I will check it out. And thanks to all that helped with this. May your game dev journey be fruitful. Cheers! 🥂 NOTE: I've been trying to post this thank you for almost an hour. Serious issues with this site/forum. Jarrod Davis |
Mark Oates
Member #1,146
March 2001
|
edit: Note to have the align (0.5, 0.5) work as expected, you will need to set the camera.size.x and camera.size.y to the width and height of your display. There are some caveats. For example, if your display width/height is undetermined (as if you are creating a fullscreen display with ALLEGRO_FULLSCREEN_WINDOW, and will ultimately may have an undetermined resolution), you may have some quirks to work out. I recommend setting up a projection on your display bitmap with al_use_projection_transform so that your virtual resolution remains consistent. Also, when using Placement2D as a camera with start_reverse_transform(), the scale property is inverted. For example, when placing sprites and using start_transform(), a scale of 2.0 will show the sprite as being twice as big on the screen. However, when using a start_reverse_transform(), a scale of 2.0 will shrink the zoom by half, because the scale is (1 / 2.0). I haven't thought this through, it might be a good idea to eventually have the reverse transform invert the scale so it's more intuitive. However as it is now, it's mathematically symmetrical so I'm not 100% sure which path is the best. -- |
tinyBigGAMES
Member #17,458
February 2020
|
Hi, ok, I was wondering why they were so HUGE, . Can you explain using placement a bit more? I got the camera working as I need. I tried the placement, but it did not seem like it was working. I do understand now why it was so large. Jarrod Davis |
ryonagana
Member #6,623
November 2005
|
is it wrong do this way? 1 typedef struct CAMERA2D {
2 float x;
3 float y;
4 int w;
5 int h;
6 ALLEGRO_TRANSFORM camera_transform;
7 }CAMERA2D;
8
9 al_identity_transform(&c->camera_transform);
10 al_translate_transform(&c->camera_transform, -c->x, -c->y);
11 al_scale_transform(&c->camera_transform, scale_x,scale_y);
12 al_use_transform(&c->camera_transform);
c++ |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Transformations are the easiest way to do a camera. Basically, you translate to the negative camera position, scale and rotate, and then un-translate the camera position. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|