I don't understand how scrolling works
zero volt

I need some points that has to do with scrolling in allegro 5. maybe a tutorial could help.

RPG Hacker

Simple scrolling is actually quite easy. Just save the x and y coordinate of your camera somewhere, then, whenever you draw your level, substract these coordinates from the x and y of your level.

zero volt

So let's suppose that my level is a background 5000 X 3000, and then after drawing this background I draw the character. but now when I move the character how can I move the background as well to show other objects drawn in the background? the only function I know is : al_draw_bitmapt(), which draws the background bitmap at the position wanted.

you think you have some links to camera scrolling tutorial using allegro 5?

RPG Hacker

You need to use the same camera coordinates for all level-objects you draw a frame and substract these from all their positions.

zero volt

First: is it okay to draw something that is outside the boundaries of my screen? for example can I do this : al_draw_bitmap(image, -500, -1000, 0)? I am positioning the image far away from the boundaries of the display. would that harm the performance of my game?

Second: you said to change the position of all the objects, doesn't that requires a lot of work to change their position every time the character moves?

Mark Oates

Camera scrolling is considered simple enough that you probably won't find a tutorial on it. It's very straight forward.

Essentially, you'll have a camera:

```float camera_x = 0;
float camera_y = 0;
```

And whenever you draw things, you subtract the camera_x and camera_y coordinates from its position.

```// draw your background
al_draw_bitmap(background_bmp, background_x - camera_x, background_y - camera_y, 0);

// draw the player
al_draw_bitmap(player_bmp, player_x - camera_x, player_y - camera_y, 0);
```

Then, whenever you change camera_x and camera_y, the objects will be scrolled.

RPG Hacker
zero volt said:

is it okay to draw something that is outside the boundaries of my screen? [...] would that harm the performance of my game?

It would harm the performance, yes. I don't know how bad the performance loss would be (ideally, the graphics card would discard every off-screen pixel, anyways), but there would definitely be a performance less that would get bigger the more you draw. This is especially true when drawing tilemaps, where you would be iterating over tiles that don't get drawn. Therefore it's best to sort out all stuff that isn't currently on-screen before rendering and only render stuff that's actually visible.

Quote:

you said to change the position of all the objects, doesn't that requires a lot of work to change their position every time the character moves?

Well, firstly, you don't really change their positions. You only change their positions in your update code. In your render code, you don't change their positions, but substract the camera position from their current position (in a temporary, local variable or whatever). Basically, see the example of Mark Oates. Secondly, what do you mean by "a lot of work"? Do you mean "work" in terms of "CPU cost" or "work" in terms of "coding complexity"? If the first one, then no, it shouldn't be much of a problem to render all of your objects and apply the camera transformation to them once a frame (that's about 30 to 60 times a second, depending on your desired frame rate), at least when done right. If the second one, then no, something like that isn't hard to code. You really only need a single for loop and have to iterate over all your game objects.

zero volt

Thanks RPG and Mark! that helped alot, my camera is working !!

I also wanted to make sure if this logic is accurate for positioning the camera:

```if(bouncer_x > SCREEN_W / 2 + camera_x)
camera_x += 15.0;

if(bouncer_x < SCREEN_W / 2 + camera_x)
camera_x -= 15.0;

if(bouncer_y > SCREEN_H / 2 + camera_y)
camera_y += 15.0;

if(bouncer_y < SCREEN_H / 2 + camera_y)
camera_y -= 15.0;
```

RPG Hacker

Depends on what you want to achieve.

In general, though, something like

camera_x += 15.0;

isn't a good idea unless you're going for a fix frame rate, which might be easier to start with, but usually people go for a variable frame rate, so something like

camera_x += CAMERA_SPEED_PER_SECOND * deltaTimeCurrentFrame;

is usually better.

zero volt

You mean something like when I want the character to run so I would want the camera to change its speed as well?

I'm looking right now on transformation and translation, do you think this is a good way to change the camera?

RPG Hacker
zero volt said:

You mean something like when I want the character to run so I would want the camera to change its speed as well?

Not neccessarily, CAMERA_SPEED_PER_SECOND can be a constant. It's only if your game is running on slower hardware that might not always be able to run your game at 30 or 60 FPS. For example, imagine your game can only run at 25 FPS for some time on certain PCs. It's good when the user doesn't notice minor FPS changes. This can be achieved by variable time steps. Though now that I look at your code again, what I said actually wasn't correct. Variable time steps only apply to stuff that happens every frame. Like the player position, which is updated every frame. Since you're only updating the camera position once at certain times, just 15.0f might actually be better here. Although the way you handle the camera in general seems very weird. I can imagine it looking quite shaky in the final game.

Quote:

I'm looking right now on transformation and translation, do you think this is a good way to change the camera?

It may be for some games, like 3D games or games with only few images. It's probably not the best way for tilemap-based games.

zero volt

This is my loop:

1void CameraUpdate(float *cameraPosition, float x, float y, int width, int height) 2{ 3 cameraPosition[0] = -(SCREEN_W / 2) + (x + width / 2); 4 cameraPosition[1] = -(SCREEN_H /2) + (y + height / 2); 5 6} 7 8... 9 10 while(!doexit) 11{ 12 ALLEGRO_EVENT ev; 13 al_wait_for_event(event_queue, &ev); 14 15 if(ev.type == ALLEGRO_EVENT_TIMER) { 16 if(key[KEY_UP]) { 17 bouncer_y -= 15.0; 18 } 19 20 if(key[KEY_DOWN]) { 21 bouncer_y += 15.0; 22 } 23 24 if(key[KEY_LEFT]) { 25 bouncer_x -= 15.0; 26 } 27 28 if(key[KEY_RIGHT]) { 29 bouncer_x += 15.0; 30 } 31 32 33 CameraUpdate(cameraPosition, bouncer_x, bouncer_y, 32, 32); 34 al_identity_transform(&camera); 35 al_translate_transform(&camera, -cameraPosition[0], -cameraPosition[1]); 36 al_use_transform(&camera); 37 38 redraw = true; 39} 40 41... 42 43if(redraw && al_is_event_queue_empty(event_queue)) { 44 redraw = false; 45 al_clear_to_color(al_map_rgb(0,0,0)); 46 al_draw_bitmap(image, image_x - camera_x, image_y - camera_y, 0); 47 al_draw_bitmap(bouncer, bouncer_x - camera_x, bouncer_y - camera_y, 0); 48 al_flip_display(); 49}

What do you think?