1

I'm currently making an awesome (in my mind) zombie game and I need to know a good way to make a camera. I am using the Slick2d library along with MarteEngine for java.

I'm kinda new to java and jumped straight into a library before really getting deep into swing and such so this is probably a lack of graphics knowledge. I read on a tutorial that you can't actually move the window of the game on the map so instead you need to move the map and objects to make it seem like the camera is moving.

If I was to do it this way it seems like it would be very resource intensive. I would have to loop through every zombie, survivor, object, hitbox, etc to move their coordinates. I've already tried this method once and things weren't really moving the same speed. That may have been due to me handling it with different update speeds.

I've seen a few things on using graphics.translate but I don't really understand it. So.. any suggestions to making a camera move would be awesome! Thanks in advance.

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
Paha
  • 99
  • 1
  • 1
  • 8
  • 1
    You could also look here http://gamedev.stackexchange.com/questions/53541/sidescrolling-troubles/53617#53617 – Savlon May 27 '14 at 00:27

2 Answers2

11

You can definitely move the camera. See my answer to this question explaining how to move the camera, render the world relative to said camera, and some other useful tips on how to do this and how to decide what to draw on the screen as the camera moves.

While it's totally possible to use translate(x, y), that alone doesn't solve clipping issues (how to know what to draw on the screen), and it's not a catch all. Also, when you think about it, there's really not much of a difference between translating the surface and moving the camera. It's all relative, and so long as the pixels are moving in the right direction, it doesn't really matter if you're "moving the camera relative to the world" or "moving the world relative to the camera" - they're essentially the same operation.

As far as Swing is concerned, be glad you didn't start there. Swing is designed for desktop applications with windows, menus, buttons, complex event systems, and the like. For a number of reasons Swing is terrible for games, not the least of which is the way the rendering pipeline works in Swing; it's fine for desktop apps, but becomes a pit of despair for games and most types of rendering that need to be real-time, and graphics intensive. This is all okay because Swing wasn't built to solve the problems of game developers anyway.

Community
  • 1
  • 1
jefflunt
  • 33,527
  • 7
  • 88
  • 126
  • Thanks for that, your post is awesome. So basically a camera will be the viewport of the game and you render everything offset by that window? So if my camera starts at (0,0) and I move it to (100,100) then I would something originally at (40,40) at (140,140) now? – Paha May 12 '12 at 17:04
  • That last comment was horribly wrong. I meant if you "move' your camera to (40,40) then the object would move closer to you by 40x and 40y. And then only render it when it's inside the camera range. – Paha May 12 '12 at 17:29
  • Yeah, so if a game object is at (100, 100) - **world** coordinates - and the upper-left corner of the camera is at (0, 0) then the object is drawn at (100, 100) - **screen** coordinates. If you move the camera to (40, 40) - **world** coordinates - then the object at **world** coordinates (100, 100) is now drawn at (60, 60) - **screen** coordinates. That is, (100-40, 100-40) = (60, 60). – jefflunt May 12 '12 at 21:11
  • 1
    So it's really just keeping track of of a abstract "camera" that offsets everything that is drawn. So I would just increment/decrement values when I want the camera moved and then draw objects based on that? – Paha May 13 '12 at 01:11
  • Exactly. That's all it takes for your basic 2D game rendering. – jefflunt May 13 '12 at 04:13
2

You're probably looking for, yes, the translate(x, y) method of the Graphics class. This method is available from both the standard Java Swing/AWT Graphics class as well as the Slick2D version, so keep in mind that this is not a Slick2D-specific feature.

What translate does is move the origin point of all future drawing operations. What does this mean? Well, keep in mind that the origin point is usually at (0, 0). As such, drawing a point at position (40, 50) will draw to the screen position (40, 50). However, translate() moves this reference point, which in turn affects all other drawing operations.

For example, doing translate(50, 60) would move the origin point 50 pixels to the right on the x axis and 60 pixels down on the y axis (since in computer programmer, larger y values are lower on the screen). Then, drawing a point at (40, 50) will actually draw to the screen at (40 + 50, 50 + 60), or (90, 110). This is the power of using translate().

It's usually a good idea to move your origin point back to (0, 0) once you're done drawing, or things could get screwed up. However, doing translate(0, 0) will not accomplish this task, and will in fact do absolutely nothing at all. This is because the translate method moves the origin to a relative point. Instead, just make sure that for every call translate(x, y), you have another call translate(-x, -y). This will keep the origin point from getting out of hand.

If you want to use this method to have the camera follow one of your entities, it is important to notice that you want to translate the origin using the negative of that entity's position. For instance, to follow a player with a position vector 'pos':

g.translate(-player.pos.x, -player.pos.y);

// Render everything

g.translate(player.pos.x, player.pos.y);

This is because you want the background to move to the left when the player moves to the right, otherwise you'll have everything following the player.

Kabbotta
  • 15
  • 5
Alexis King
  • 43,109
  • 15
  • 131
  • 205
  • Awesome explanation, thanks. Another question... if there was something I didn't want to be translated how would I handle this? MarteEngine basically adds everything to one world so if I translate the world if moves EVERYTHING (which is awesome) but I made a UI entity that also moves. Again, thanks for the wonderful explanation; – Paha May 12 '12 at 05:21
  • @Paha No problem, that's why this site exists. :) Anyway, the only way to keep something from being translated is to either (1) undo the translation while you draw that object or (2) subtract the translation origin from the point where you draw the unit to negate the translation's effects. – Alexis King May 12 '12 at 05:38
  • Hmm not sure if I can use translation then. MarteEngine auto renders everything for me which means I'd have to go and override all the renders. It also throws my hero's rotation methods WAY off. I'll keep working with it and see what I can do though. – Paha May 12 '12 at 06:08