Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » 2d camera

This thread is locked; no one can reply to it. rss feed Print
2d camera
tinyBigGAMES
Member #17,458
February 2020
avatar

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
Owner/Lead Developer
tinyBigGAMES LLC

Chris Katko
Member #1,881
January 2002
avatar

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:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

DanielH
Member #934
January 2001
avatar

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
avatar

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)
// all drawing between start/end will be affected by the camera transform
camera2d_end(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
Owner/Lead Developer
tinyBigGAMES LLC

Chris Katko
Member #1,881
January 2002
avatar

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:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Mark Oates
Member #1,146
March 2001
avatar

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();

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

tinyBigGAMES
Member #17,458
February 2020
avatar

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
Owner/Lead Developer
tinyBigGAMES LLC

Mark Oates
Member #1,146
March 2001
avatar

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.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

tinyBigGAMES
Member #17,458
February 2020
avatar

Hi, ok, I was wondering why they were so HUGE, ;D. 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
Owner/Lead Developer
tinyBigGAMES LLC

ryonagana
Member #6,623
November 2005

is it wrong do this way?

#SelectExpand
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
avatar

Go to: