Add a Camera
Object to move game view according to a target position in the game play area. the target must be
an Entity
.
Camera
move.Here are:
The Camera object will drive the rendering view port to follow a GameObject
target
, with a certain delay fixed by
the tween
factor value.
The Camera
class will inherit from Entity
and introduce 3 new attributes:
And the main Camera
processing will be a dedicated computing on the target position, according to the tween delay
factor:
cam.pos = cam.pos
+ (target.pos-(viewport.size-target.size))
x 0.5
x tweenFactor
x elapsedTime
So the update method in the Camera object will be :
class Camera {
//...
public GameObject update(double elapsed) {
x += target.x - ((viewport.getWidth() - target.width)) * 0.5 * tween * elapsed;
y += target.y - ((viewport.getHeight() - target.height)) * 0.5 * tween * elapsed;
}
//...
}
The class App
must be enhanced with a new Camera
attribute name activeCamera
, and initialize it during the
App#create()
method processing:
class App implements Game {
//...
private Camera activeCamera;
//...
@Override
public void create() {
//...
setActiveCamera((Camera) new Camera("cam01")
.setTarget(player)
.setTween(0.2)
.setViewport(new Rectangle2D.Double(
0.0, 0.0,
((double) screenWidth), ((double) screenHeight))));
}
//...
public void setActiveCamera(Camera activeCamera) {
this.activeCamera = activeCamera;
this.renderer.setCurrentCamera(activeCamera);
}
//...
}
The class Renderer
now need to use a current Camera
instance to move the rendering viewport to the currentCamera
position, and apply this move on concerned GameObject
.
class Renderer {
//..
private Camera currentCamera;
public void draw(Map<String, Object> attributes) {
Graphics2D g = (Graphics2D) buffer.getGraphics();
//...
// draw all the things you need.
game.getEntityManager().getEntities()
.stream()
.sorted((o1, o2) -> o1.getLayer() > o2.getLayer() ? 1 : (o1.getPriority() > o1.getPriority() ? 1 : -1))
.forEach(e -> {
// move to Camera viewport if object not stick to Camera
if (Optional.ofNullable(currentCamera).isPresent() && !e.isStickToCamera()) {
g.translate(-currentCamera.x, -currentCamera.y);
}
// draw object
drawEntity(g, e);
// move back from Camera viewport if object not stick to Camera
if (Optional.ofNullable(currentCamera).isPresent() && !e.isStickToCamera()) {
g.translate(-currentCamera.x, currentCamera.y);
}
});
// draw entity's display debug information
if (game.getDebugMode() > 0) {
game.getEntityManager().getEntities()
.stream()
.sorted((o1, o2) -> o1.getLayer() > o2.getLayer() ? 1 : (o1.getPriority() > o1.getPriority() ? 1 : -1))
.forEach(e -> {
// move to Camera viewport if object not stick to Camera
if (Optional.ofNullable(currentCamera).isPresent() && !e.isStickToCamera()) {
g.translate(-currentCamera.x, -currentCamera.y);
}
// draw Debug information for the Entity.
drawDebugInformation(g, e);
// move back from Camera viewport if object not stick to Camera
if (Optional.ofNullable(currentCamera).isPresent() && !e.isStickToCamera()) {
g.translate(-currentCamera.x, currentCamera.y);
}
});
// draw some debug information.
drawDisplayDebugLine(g, attributes);
}
// release Graphics API
g.dispose();
}
//...
public void setCurrentCamera(Camera currentCamera) {
this.currentCamera = currentCamera;
}
}
With this new chapter, we implemented a Camera
object that tracks a GameObject
with a certain delay in the following
moves.
According to our project, you will find this corresponding code with the
tag create-camera in
the Game101 GitHub repository
That’s all folk !
McG.