Camera for 2d game

2019-06-04 02:08发布

问题:

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.

回答1:

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.



回答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.