package com.jonathan.survivor.renderers;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.jonathan.survivor.Survivor;
import com.jonathan.survivor.World;
import com.jonathan.survivor.World.WorldState;
import com.jonathan.survivor.entity.Player;
/**
* Renders the world and its GameObjects. Also stores the camera used to view the world.
* @author Jonathan
*
*/
public class WorldRenderer
{
/** Stores the width and height of the world. This is the viewable region of the world, in world units. In other words, the camera size.
* The size is changed inside the resize() method according the aspect ratio of the screen. */
private float worldWidth = Survivor.DEFAULT_WORLD_WIDTH;
private float worldHeight = Survivor.DEFAULT_WORLD_HEIGHT;
/** Stores the world whose level and gameObjects we render. */
private World world;
/** Stores the SpriteBatcher used to draw the GameObjects. */
private SpriteBatch batcher;
/** Stores the OrthographicCamera used to view the world. */
private OrthographicCamera worldCamera;
/** Stores the LevelRenderer used to render every type of level. */
private LevelRenderer levelRenderer;
/** Stores the GameObjectRenderer which takes the world's data and renders it to the screen with sprites. */
private GameObjectRenderer goRenderer;
/** Holds the AnimationRenderer instance used to render all of the Spine animations which overlay the screen. */
private AnimationRenderer animationRenderer;
/** Holds the EffectRenderer instance used to render all of the small effects on screen, such as the crosshairs. */
private EffectRenderer effectRenderer;
/** Creates a WorldRenderer instance used to draw the given world instance with the given SpriteBatch. */
public WorldRenderer(World world, SpriteBatch batcher)
{
//Populates the member variables with their respective constructor arguments.
this.world = world;
this.batcher = batcher;
//Creates the camera used to navigate and view the world. Initialized to the default width and height of the world.
worldCamera = new OrthographicCamera(worldWidth, worldHeight);
//Creates a LevelRenderer from which the level geometry is drawn. We pass in the camera so that geometry is drawn to the world camera.
levelRenderer = new LevelRenderer(batcher, worldCamera);
//Creates a GameObject renderer from the world. All gameObjects in the world will be drawn to the worldCamera using the specified SpriteBatch.
goRenderer = new GameObjectRenderer(world, batcher, worldCamera);
//Instantiates the AnimationRenderer, which draws all of the Spine animations which are screen overlays, such as the versus animation.
animationRenderer = new AnimationRenderer(world, batcher, worldCamera);
//Creates the EffectRenderer instance used to render all of the small effects on screen, such as the crosshairs on each gun.
effectRenderer = new EffectRenderer(world, batcher, worldCamera);
}
/** Called every frame when the game is running to update the position of the camera. MUST be called before render() method. */
public void updateCamera()
{
//If the player is not in combat mode, the camera follows the center of the player.
if(world.getWorldState() != WorldState.COMBAT && world.getWorldState() != WorldState.KO_ANIMATION)
{
//Make the camera follow the center of the player.
worldCamera.position.x = world.getPlayer().getX();
worldCamera.position.y = world.getPlayer().getY() + Player.COLLIDER_HEIGHT/2;
}
//Else, if the player is in combat mode
else
{
//The camera's bottom-center position is locked to (0,0).
worldCamera.position.x = 0;
worldCamera.position.y = worldCamera.viewportHeight/2;
}
//Updates the position of the camera.
worldCamera.update();
}
/** Called every frame to render the contents of the world and update the camera. */
public void render(float deltaTime)
{
//Draws the world's currently active level to the screen using the LevelRenderer.
levelRenderer.render(world.getLevel());
//Render the gameObjects of the world to the screen.
goRenderer.render(deltaTime);
//Renders all of the Spine overlay animations that should be shown.
animationRenderer.render(deltaTime);
//Draws all of the small effects to the screen, such as the crosshairs or trajectory lines for each weapon.
effectRenderer.render(deltaTime);
}
/** Retrieves the world camera used to render the world. */
public OrthographicCamera getWorldCamera() {
return worldCamera;
}
/** Sets the world camera used to render the world. */
public void getWorldCamera(OrthographicCamera worldCamera) {
this.worldCamera = worldCamera;
}
/** Called when the screen is resized, or when the world renderer is first created. Resizes the camera to adjust to the new aspect ratio. Note that the parameters
* specify the new width and height that the camera should have. Third parameter specifies a screen scale. This should be the factor the view frustum had to be
* stretched to fit the target device. The level's line thickness is multiplied by this factor to compensate for a larger or smaller screen. */
public void resize(float worldWidth, float worldHeight, float screenScale)
{
//Updates the width and height of the world. This is the viewable area of the world. I.e., the camera's size.
worldWidth = worldWidth;
worldHeight = worldHeight;
//Updates the size of the camera to the values passed as parameters. The parameters specify the new size the camera should have. It was computed inside GameScreen.
worldCamera.viewportWidth = worldWidth;
worldCamera.viewportHeight = worldHeight;
//Tells the level renderer to resize the lines drawn by the given screen scale for resolution independency.
levelRenderer.resize(screenScale);
}
}