package net.fourbytes.shadow; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Array; import net.fourbytes.shadow.blocks.BlockType; import net.fourbytes.shadow.systems.IParticleManager; import java.lang.reflect.Constructor; public abstract class GameObject { private boolean idSet = false; private long id = 0L; public final long getID() { if (!idSet) { setID(Shadow.rand.nextLong()); return id; } return id; } public final void setID(long id) { idSet = true; if (layer != null && layer.level != null) { layer.level.goIDMap.remove(this.id); layer.level.goIDMap.put(id, this); } this.id = id; } public boolean blending = true; public float alpha = 1f; public Layer layer; public Chunk chunk; public Vector2 pos = new Vector2(0, 0); public Rectangle rec = new Rectangle(0, 0, 0, 0); public Rectangle renderoffs = new Rectangle(0, 0, 0, 0); public boolean solid = true; public float slowdown = 0.7f; public Color light = new Color(1f, 1f, 1f, 0f); public boolean passSunlight = false; public Color tintSunlight = new Color(1f, 1f, 1f, 1f); public Color tintDarklight = new Color(0f, 0f, 0f, 1f); public int[] imgIDs = {0}; public GameObject(Vector2 pos, Layer layer) { this.pos = pos; setSize(1f, 1f); this.layer = layer; } public void setSize(float w, float h) { rec.set(0f, 0f, w, h); } public boolean imgupdate = true; public boolean texupdate = true; public Image[] images = new Image[1]; public TextureRegionDrawable[] trds = new TextureRegionDrawable[1]; public static boolean reuseImage = true; public Image getImage(int id) { Image img = images[id]; if (texupdate || img == null) { TextureRegion tex = getTexture(id); if (tex == null) { System.out.println("("+this+(this instanceof Block?(", "+((Block)this).subtype+")"):")")+ " getTexture("+id+") == null!"); tex = Images.getTextureRegion("white"); } if (!reuseImage) { img = new Image(tex); images[id] = img; } else { if (img == null) { trds[id] = new TextureRegionDrawable(tex); img = new Image(trds[id]); images[id] = img; } else { trds[id].setRegion(tex); img.setDrawable(trds[id]); } } return img; } else { return img; } } public abstract TextureRegion getTexture(int id); public void tick(float delta) { } public void frame(float delta) { } public void preRender() { if (imgupdate || texupdate) { for (int id : imgIDs) { Image img = getImage(id); //i.setPosition(pos.x * Shadow.dispw/Shadow.vieww, pos.y * Shadow.disph/Shadow.viewh); img.setPosition(pos.x + renderoffs.x, pos.y + renderoffs.y); img.setSize(rec.width + renderoffs.width, rec.height + renderoffs.height); img.setScaleY(-1f); renderCalc(id, img); } } imgupdate = false; texupdate = false; } public Color[] baseColors = new Color[1]; public void renderCalc(int id, Image img) { tint(id, img); } public void tint(int id, Image img) { Color c = img.getColor(); if (baseColors[id] == null) { baseColors[id] = new Color(c); } c.set(baseColors[id]); if (layer != null) { c.mul(layer.tint); } } public void render() { for (int id : imgIDs) { Image img = getImage(id); Color imgc = img.getColor(); Shadow.spriteBatch.setColor(imgc.r, imgc.g, imgc.b, imgc.a * alpha); img.getDrawable().draw(Shadow.spriteBatch, pos.x + renderoffs.x, pos.y + rec.height + renderoffs.y, rec.width + renderoffs.width, -rec.height + renderoffs.height); } } public int pixfac = 1; public static int pixffac = 1; Color c = new Color(0f, 0f, 0f, 0f); Color cc = new Color(0f, 0f, 0f, 0f); Color ccc = new Color(0f, 0f, 0f, 0f); Vector2 ppos = new Vector2(); public Array<Particle> pixelify() { int fac = pixfac * pixffac; if (fac < 0) { fac = 1; } //pixfac = 2; //DEBUG LINE, COMMENT WHOLE LINE OUT IF NOT DEBUGGING! Array<Particle> particles = new Array<Particle>(); for (int id : imgIDs) { Image img = getImage(id); TextureRegion texreg = getTexture(id); Texture tex = texreg.getTexture(); TextureData texdata = tex.getTextureData(); if (!texdata.isPrepared()) { texdata.prepare(); } Pixmap pixmap = texdata.consumePixmap(); int tx = texreg.getRegionX(); int ty = texreg.getRegionY(); int tw = texreg.getRegionWidth(); int th = texreg.getRegionHeight(); float w = rec.width; float h = rec.height; float pixw = w / tw * fac; float pixh = h / th * fac; for (int yy = ty; yy < ty + th; yy += fac) { for (int xx = tx; xx < tx + tw; xx += fac) { int rgba = pixmap.getPixel(xx, yy); for (int yyy = 0; yyy < fac; yyy++) { for (int xxx = 0; xxx < fac; xxx++) { c.set(0f, 0f, 0f, 0f); cc.set(0f, 0f, 0f, 0f); Color.rgba8888ToColor(c, rgba); Color.rgba8888ToColor(cc, pixmap.getPixel(xx + xxx, yy + yyy)); c.mul(0.5f); cc.mul(0.5f); c.add(cc); rgba = Color.rgba8888(c); } } //System.out.println("X: "+xx+"; Y: "+yy+"; RGBA: "+Integer.toHexString(rgba)); Color.rgba8888ToColor(ccc, rgba); ccc.mul(img.getColor()); if (c.a < 0.0625f) continue; ppos.set(pos.x + ((xx - tx) * pixw / fac) + renderoffs.x, pos.y + ((yy - ty) * pixh / fac) + renderoffs.y); Particle pp = layer.level.systems.get(IParticleManager.class).create("PixelParticle", ppos, layer, ccc, pixw, 0); layer.add(pp); particles.add(pp); } } if (texdata.disposePixmap()) { pixmap.dispose(); } } return particles; } public GameObject duplicate() { Class<? extends GameObject> c = getClass(); GameObject clone = null; try { Constructor<? extends GameObject> constr = c.getConstructor(Vector2.class, Layer.class); constr.setAccessible(true); clone = constr.newInstance(pos, layer); } catch (Exception e) { try { if (this instanceof Block) { clone = BlockType.getInstance(((Block)this).subtype, pos.x, pos.y, layer); //clone = (GameObject) c.getConstructor(Vector2.class, Layer.class, BlockType.class).newInstance(new Vector2(pos), layer, type); } } catch (Exception e1) { System.err.println("e:"); e.printStackTrace(); System.err.println("e1:"); e1.printStackTrace(); } } return clone; } public void collide(Entity e) { } }