package net.mostlyoriginal.ns2d.system.render; import com.artemis.Aspect; import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.EntitySystem; import com.artemis.annotations.Wire; import com.artemis.utils.ImmutableBag; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import net.mostlyoriginal.ns2d.component.Anim; import net.mostlyoriginal.ns2d.component.Pos; import net.mostlyoriginal.ns2d.system.passive.AssetSystem; import net.mostlyoriginal.ns2d.system.passive.CameraSystem; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * @author Daan van Yperen */ @Wire public class AnimRenderSystem extends EntitySystem { private ComponentMapper<Pos> pm; private ComponentMapper<Anim> sm; private CameraSystem cameraSystem; private AssetSystem assetSystem; private SpriteBatch batch; private List<Entity> sortedEntities = new ArrayList<Entity>(); private boolean sortedDirty = false; public Comparator<Entity> layerSortComperator = new Comparator<Entity>() { @Override public int compare(Entity e1, Entity e2) { return sm.get(e1).layer.compareTo(sm.get(e2).layer); } }; private float age; public final ShaderProgram shimmerProgram; public AnimRenderSystem() { super(Aspect.getAspectForAll(Pos.class, Anim.class)); shimmerProgram = new ShaderProgram(Gdx.files.internal("shader/shimmer.vertex"), Gdx.files.internal("shader/shimmer.fragment")); if ( !shimmerProgram.isCompiled() ) throw new RuntimeException("Compilation failed." + shimmerProgram.getLog()); batch = new SpriteBatch(2000, shimmerProgram); } @Override protected void begin() { age += world.delta; batch.setProjectionMatrix(cameraSystem.camera.combined); batch.begin(); shimmerProgram.setUniformf("iGlobalTime", age); batch.setColor(1f, 1f, 1f, 1f); } @Override protected void end() { batch.end(); } @Override protected void processEntities(ImmutableBag<Entity> entities) { if (sortedDirty) { sortedDirty = false; Collections.sort(sortedEntities, layerSortComperator); } for (Entity entity : sortedEntities) { process(entity); } } protected void process(final Entity entity) { final Anim anim = sm.get(entity); final Pos pos = pm.get(entity); anim.age += world.delta * anim.speed; batch.setColor( anim.color ); drawAnimation(anim, pos, anim.id); } private void drawAnimation(final Anim animation, final Pos position, String id) { final com.badlogic.gdx.graphics.g2d.Animation gdxanim = assetSystem.get(id); if ( gdxanim == null) return; final TextureRegion frame = gdxanim.getKeyFrame(animation.age, true); if ( animation.flippedX) { batch.draw(frame.getTexture(), (int)position.x, (int)position.y, animation.ox == Anim.ORIGIN_AUTO ? frame.getRegionWidth() * animation.scale * 0.5f : animation.ox, animation.oy == Anim.ORIGIN_AUTO ? frame.getRegionHeight() * animation.scale * 0.5f : animation.oy, frame.getRegionWidth() * animation.scale, frame.getRegionHeight() * animation.scale, 1f, 1f, animation.rotation, frame.getRegionX(), frame.getRegionY(), frame.getRegionWidth(), frame.getRegionHeight(), true, false); } else if ( animation.rotation != 0 ) { batch.draw(frame, (int)position.x, (int)position.y, animation.ox == Anim.ORIGIN_AUTO ? frame.getRegionWidth() * animation.scale * 0.5f : animation.ox, animation.oy == Anim.ORIGIN_AUTO ? frame.getRegionHeight() * animation.scale * 0.5f : animation.oy, frame.getRegionWidth() * animation.scale, frame.getRegionHeight() * animation.scale, 1, 1, animation.rotation); } else { batch.draw(frame, (int)position.x, (int)position.y, frame.getRegionWidth() * animation.scale, frame.getRegionHeight() * animation.scale); } } @Override protected boolean checkProcessing() { return true; } @Override protected void inserted(Entity e) { sortedEntities.add(e); sortedDirty = true; } @Override protected void removed(Entity e) { sortedEntities.remove(e); } }