moved rendering from the Master to the RenderEngine

This commit is contained in:
nora 2020-12-31 17:03:28 +01:00
parent 7e90017e8f
commit 39558c94c7
9 changed files with 231 additions and 90 deletions

View file

@ -0,0 +1,88 @@
package core.general;
import core.renderer.Drawable;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* The {@code LayerManager} works with multiple render layers that contain the Renderers
*/
public class LayerManager {
/**
* A {@code List} of the {@code Lists} which are the layers
*/
private final List<List<Drawable>> layers;
/**
* The buffer of newly added Renderers
*/
private final List<Drawable> buffer = new ArrayList<>();
/**
* Create a new {@code LayerManager}
*/
public LayerManager() {
layers = new ArrayList<>();
}
/**
* Draw all {@code Renderers}
* @param g2d
*/
public void drawAll(Graphics2D g2d){
layers.forEach(e -> e.forEach(f -> f.draw(g2d)));
}
/**
* Add a new {@code Renderer} to the buffer
* @param d
*/
public void addToRendererBuffer(Drawable d){
buffer.add(d);
}
/**
* Add a new {@code Renderer} to the render layers. Should only be called between renderings.
* Creates new render layers if the requested layer doesn't exist
* @param d The Renderer
*/
private void addRenderer(Drawable d) {
int layer = d.getLayer();
if (layer < 0) {
throw new IllegalArgumentException("Layer must be at least 0");
}
//layer exists check
int layerDif = layer - (layers.size() - 1);
if (layerDif > 0) {
for (int i = 0; i < layerDif; i++) {
layers.add(new ArrayList<>());
}
}
layers.get(layer).add(d);
}
/**
* Remove a {@code Renderer} from the render layers.
* <p>If the object should only temporarily be invisible, change its {@code isVisible} field</p>
* @param d The {@code Renderer}
* @return {@code true} if the element exists in its layer
*/
public boolean removeRenderer(Drawable d) {
return layers.get(d.getLayer()).remove(d);
}
/**
* Flushes the buffer to the render layers
*/
public void flush(){
buffer.forEach(this::addRenderer);
buffer.clear();
}
}

View file

@ -25,7 +25,7 @@ class Main extends JFrame {
private void initUI() {
master = new Master();
add(master);
add(master.getRenderEngine());
Init.init();

View file

@ -5,7 +5,6 @@ import core.objects.core.CollGameObject;
import core.physics.Collidable;
import core.physics.Collision;
import core.objects.base.DebugPos;
import core.physics.hitboxes.Hitbox;
import core.objects.core.GameObject;
import core.renderer.Drawable;
import objects.Init;
@ -13,11 +12,12 @@ import objects.Init;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* The main object that controls everything
*/
public class Master extends JPanel {
public class Master {
/**
* The ratio of height to width.
@ -37,35 +37,29 @@ public class Master extends JPanel {
/**
* All GameObjects that exist
*/
private final ArrayList<GameObject> objects;
/**
* All GameObjects that can be drawn
* Has different render layers, 0 is on the bottom
*/
private final ArrayList<ArrayList<Drawable>> drawables;
private final List<GameObject> objects;
/**
* All physics objects that exist
*/
private final ArrayList<Collidable> collidables;
private final List<Collidable> collidables;
/**
* Stores all GameObjects that were created during a frame
*/
private final ArrayList<GameObject> objectBuffer;
private final List<GameObject> objectBuffer;
/**
* All physics objects that exist
*/
private final ArrayList<Collidable> collidablesBuffer;
private final List<Collidable> collidablesBuffer;
/**
* The current width and height of the game area
* The {@code RenderEngine} that handles everything about rendering
*/
private int w, h;
private final RenderEngine renderEngine = new RenderEngine();
/**
* Create a new master object
@ -77,41 +71,12 @@ public class Master extends JPanel {
objectBuffer = new ArrayList<>();
collidables = new ArrayList<>();
collidablesBuffer = new ArrayList<>();
drawables = new ArrayList<>();
drawables.add(new ArrayList<>());
}
public static Master getMaster() {
return master;
}
/**
* The mein drawing method, handles everything about drawing
*
* @param g
*/
@Deprecated
private void doDrawing(Graphics g) {
if (getWidth() * 9 > getHeight() * 16) {
h = getHeight();
w = h / 9 * 16;
} else {
w = getWidth();
h = w / 16 * 9;
}
Graphics2D g2d = (Graphics2D) g.create();
drawables.forEach(l -> l.forEach(o -> o.draw(g2d)));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
/**
* Debug a position, creates a green dot at the position
@ -128,7 +93,7 @@ public class Master extends JPanel {
* @param pos The position
*/
private void debugPosObj(Vector2D pos, long lifeTime) {
create(new DebugPos(pos, new Vector2D(2, 2), lifeTime), 3);
create(new DebugPos(pos, new Vector2D(2, 2), lifeTime));
}
/**
@ -155,7 +120,8 @@ public class Master extends JPanel {
objects.forEach(GameObject::startUpdate);
long time2 = System.currentTimeMillis();
Input.frameReset();
repaint();
renderEngine.flush();
renderEngine.repaint();
System.out.println("Frame took " + (System.currentTimeMillis() - time) + "ms, " + (time2 - time) + "ms for update, " + (System.currentTimeMillis() - time2) + "ms for draw");
}
@ -166,7 +132,7 @@ public class Master extends JPanel {
*/
public Point getMouseLocation() {
Point p = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(p, this);
SwingUtilities.convertPointFromScreen(p, renderEngine);
return p;
}
@ -177,46 +143,22 @@ public class Master extends JPanel {
* @param obj The new object
*/
public <T extends GameObject> T create(T obj) {
create(obj, obj.getLayer());
return obj;
}
/**
* This method has to be called for every newly created GameObject
*
* @param obj The new object
* @param renderLayer The render layer the object will be put on, 0 is below everything
*/
public void create(GameObject obj, int renderLayer) {
objectBuffer.add(obj);
if (obj instanceof CollGameObject) {
collidablesBuffer.add((Collidable) obj);
}
addDrawable(obj, renderLayer);
renderEngine.addRenderer(obj);
return obj;
}
/**
* Add a new Drawable to the render list
*
* @param d The drawable
* @param layer The layer it should be put on (>=0)
*/
public void addDrawable(Drawable d, int layer) {
if (layer < 0) {
throw new IllegalArgumentException("Layer must be at least 9");
}
//layer exists check
int layerDif = layer - (drawables.size() - 1);
if (layerDif > 0) {
for (int i = 0; i < layerDif; i++) {
drawables.add(new ArrayList<>());
}
}
drawables.get(layer).add(d);
@Deprecated
public void addDrawable(Drawable d) {
renderEngine.addRenderer(d);
}
@ -251,25 +193,29 @@ public class Master extends JPanel {
}
public int getW() {
return w;
return renderEngine.getW();
}
public int getH() {
return h;
return renderEngine.getH();
}
public void destroy(GameObject gameObject) {
objectBuffer.remove(gameObject);
gameObject.getParent().removeChild(gameObject);
drawables.get(gameObject.getLayer()).remove(gameObject);
renderEngine.removeRenderer(gameObject);
if (gameObject instanceof Collidable) {
collidablesBuffer.remove(gameObject);
if (Init.DEBUG_MODE) {
drawables.get(Hitbox.HITBOX_RENDER_LAYER).remove(((CollGameObject) gameObject).getHitbox());
renderEngine.removeRenderer(((CollGameObject) gameObject).getHitbox());
}
}
}
public RenderEngine getRenderEngine() {
return renderEngine;
}
}

View file

@ -0,0 +1,103 @@
package core.general;
import core.renderer.Drawable;
import javax.swing.*;
import java.awt.*;
/**
* The {@code RenderEngine} handles the rendering of all {@code Renderers}
* c<p>The {@code RenderEngine} extends JPanel and can be integrated into a JFrame. It gets the drawcall from resizing/moving the JPanel
* or from the {@code Master}</p>
*/
public class RenderEngine extends JPanel {
/**
* The current width and height of the game area
*/
private int w, h;
/**
* The {@code LayerManager} for the render layers
*/
private final LayerManager layerManager;
/**
* Construct a new {@code RenderEngine}
*/
public RenderEngine() {
layerManager = new LayerManager();
}
/**
* The mein drawing method, handles everything about drawing
*
* @param g The {@code Graphics} object
*/
private void doDrawing(Graphics g) {
if (getWidth() * 9 > getHeight() * 16) {
h = getHeight();
w = h / 9 * 16;
} else {
w = getWidth();
h = w / 16 * 9;
}
Graphics2D g2d = (Graphics2D) g.create();
layerManager.drawAll(g2d);
}
/**
* The paintComponent method is called from Swing.
* @param g
*/
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
/**
* Add a {@code Renderer} to the scene. Gets added to the buffer
* @param d The {@code Renderer}
*/
public void addRenderer(Drawable d){
layerManager.addToRendererBuffer(d);
}
/**
* Remove a {@code Renderer} from the engine because it won't be needed anymore.
* <p>If the object should only temporarily be invisible, change its {@code isVisible} field</p>
* @param d
* @return
*/
public boolean removeRenderer(Drawable d){
return layerManager.removeRenderer(d);
}
/**
* Get the true width of the current screen
* @return The width in Java2D coordinates
*/
public int getW() {
return w;
}
/**
* Get the true height of the current screen
* @return The height in Java2D coordinates
*/
public int getH() {
return h;
}
/**
* Flush the buffer
*/
public void flush() {
layerManager.flush();
}
}

View file

@ -24,4 +24,9 @@ public abstract class Hitbox implements Drawable {
public String toString() {
return super.toString();
}
@Override
public int getLayer() {
return HITBOX_RENDER_LAYER;
}
}

View file

@ -34,7 +34,7 @@ public class RectHitBox extends Hitbox {
this.y1 = Vector2D.add(x1, new Vector2D(0, size.y));
this.y2 = Vector2D.add(x1, new Vector2D(size.x, size.y));
if (Init.DEBUG_MODE) {
Master.getMaster().addDrawable(this, HITBOX_RENDER_LAYER);
//Master.getMaster().addDrawable(this);
}
}

View file

@ -17,4 +17,10 @@ public interface Drawable {
* @param g2d The {@code Graphics2D} object given by the master
*/
void draw(Graphics2D g2d);
/**
* Returns the layer of the Drawable
* @return The render layer
*/
int getLayer();
}

View file

@ -29,8 +29,6 @@ public class RoundRectRenderer extends Renderer {
int xCenterAbs = (int) (abs.x + sizeAbs.x / 2);
int yCenterAbs = (int) (abs.y + sizeAbs.y / 2);
master.debugPos(object.getCenterPosition(), 500);
g2d.setPaint(color);
g2d.rotate(object.getRotation(), xCenterAbs, yCenterAbs);

View file

@ -41,13 +41,10 @@ public class Turret extends GameObject {
int xCenterAbs = (int) (abs.x + sizeAbs / 2);
int yCenterAbs = (int) (abs.y + sizeAbs / 2);
Master.debugPos(getMapCoords(position), 1);
g2d.rotate(rotation, xCenterAbs, yCenterAbs);
g2d.fillOval((int) abs.x, (int) abs.y, sizeAbs, sizeAbs);
Master.debugPos(abs, 1000);
//BARRELS---------------------------------------
g2d.setStroke(new BasicStroke((int) Coordinates.getWorldCoordinates(new Vector2D(object.getSize().x / barrelAmount / BARREL_THICKNESS, 0)).x, BasicStroke.CAP_BUTT,
@ -98,13 +95,11 @@ public class Turret extends GameObject {
lastShot = System.currentTimeMillis();
Vector2D shellVel = Vector2D.getUnitVector(rotation).negative().multiply(SHELL_SPEED);
//master.debugPos(centerMap);
Vector2D pos = Vector2D.rotateAround(
centerMap,
spawnPosNR,
rotation);
//master.debugPos(pos);
master.create(new Shell(pos, new Vector2D(SHELL_SIZE, SHELL_SIZE), shellVel));
}
}