Implemented sprite caching, water, grass, and improved performance

This commit is contained in:
Anuken
2017-05-19 18:08:55 -04:00
parent b8b3848e5e
commit 6709d9856d
69 changed files with 477 additions and 527 deletions

View File

@@ -15,56 +15,56 @@ public class EffectLoader{
Effect.create("place", 16, e -> {
Draw.thickness(3f - e.ifract() * 2f);
Draw.square(e.x, e.y, tilesize / 2f + e.ifract() * 3f);
Draw.clear();
Draw.reset();
});
Effect.create("spark", 10, e -> {
Draw.thickness(1f);
Draw.color(Hue.mix(Color.WHITE, Color.GRAY, e.ifract()));
Draw.spikes(e.x, e.y, e.ifract() * 5f, 2, 8);
Draw.clear();
Draw.reset();
});
Effect.create("smelt", 10, e -> {
Draw.thickness(1f);
Draw.color(Hue.mix(Color.YELLOW, Color.RED, e.ifract()));
Draw.spikes(e.x, e.y, e.ifract() * 5f, 2, 8);
Draw.clear();
Draw.reset();
});
Effect.create("break", 12, e -> {
Draw.thickness(2f);
Draw.color(Color.WHITE, Color.GRAY, e.ifract());
Draw.spikes(e.x, e.y, e.ifract() * 5f, 2, 5);
Draw.clear();
Draw.reset();
});
Effect.create("hit", 10, e -> {
Draw.thickness(1f);
Draw.color(Hue.mix(Color.WHITE, Color.ORANGE, e.ifract()));
Draw.spikes(e.x, e.y, e.ifract() * 3f, 2, 8);
Draw.clear();
Draw.reset();
});
Effect.create("shoot", 8, e -> {
Draw.thickness(1f);
Draw.color(Hue.mix(Color.WHITE, Color.GOLD, e.ifract()));
Draw.spikes(e.x, e.y, e.ifract() * 2f, 2, 5);
Draw.clear();
Draw.reset();
});
Effect.create("shoot2", 8, e -> {
Draw.thickness(1f);
Draw.color(Hue.mix(Color.WHITE, Color.SKY, e.ifract()));
Draw.spikes(e.x, e.y, e.ifract() * 2f, 1, 5);
Draw.clear();
Draw.reset();
});
Effect.create("shoot3", 8, e -> {
Draw.thickness(1f);
Draw.color(Hue.mix(Color.WHITE, Color.GOLD, e.ifract()));
Draw.spikes(e.x, e.y, e.ifract() * 2f, 1, 5);
Draw.clear();
Draw.reset();
});
Effect.create("explosion", 15, e -> {
@@ -72,7 +72,7 @@ public class EffectLoader{
Draw.color(Hue.mix(Color.ORANGE, Color.GRAY, e.ifract()));
Draw.spikes(e.x, e.y, 2f + e.ifract() * 3f, 4, 6);
Draw.circle(e.x, e.y, 3f + e.ifract() * 3f);
Draw.clear();
Draw.reset();
});
Effect.create("coreexplosion", 13, e -> {
@@ -80,21 +80,21 @@ public class EffectLoader{
Draw.color(Hue.mix(Color.ORANGE, Color.WHITE, e.ifract()));
Draw.spikes(e.x, e.y, 5f + e.ifract() * 40f, 6, 6);
Draw.circle(e.x, e.y, 4f + e.ifract() * 40f);
Draw.clear();
Draw.reset();
});
Effect.create("spawn", 23, e -> {
Draw.thickness(2f);
Draw.color(Hue.mix(Color.DARK_GRAY, Color.SCARLET, e.ifract()));
Draw.circle(e.x, e.y, 7f - e.ifract() * 6f);
Draw.clear();
Draw.reset();
});
Effect.create("ind", 100, e -> {
Draw.thickness(3f);
Draw.color("royal");
Draw.circle(e.x, e.y, 3);
Draw.clear();
Draw.reset();
});
Effect.create("respawn", respawnduration, e -> {
@@ -102,7 +102,7 @@ public class EffectLoader{
Draw.tscl(0.25f);
Draw.text("Respawning in " + (int)((e.lifetime-e.time)/60), e.x, e.y);
Draw.tscl(0.5f);
Draw.clear();
Draw.reset();
});
}
}

View File

@@ -94,12 +94,12 @@ public class Input{
Tile cursor = World.cursorTile();
//block breaking
if(Inputs.buttonDown(Buttons.RIGHT) && World.cursorNear() && cursor.artifical()
if(Inputs.buttonDown(Buttons.RIGHT) && World.cursorNear() && cursor.breakable()
&& cursor.block() != ProductionBlocks.core){
Tile tile = cursor;
breaktime += Mathf.delta();
if(breaktime >= breakduration){
Effects.effect("break", tile.entity);
if(breaktime >= tile.block().breaktime){
Effects.effect("break", tile.worldx(), tile.worldy());
Effects.shake(3f, 1f);
tile.setBlock(Blocks.air);
breaktime = 0f;

View File

@@ -17,19 +17,62 @@ import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.graphics.Cache;
import io.anuke.ucore.graphics.Caches;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.GridMap;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timers;
public class Renderer{
private static int chunksize = 32;
private static GridMap<Cache> caches = new GridMap<>();
public static void renderTiles(){
Draw.clear();
int chunksx = World.width()/chunksize, chunksy = World.height()/chunksize;
//render the entire map
if(caches.size() == 0){
for(int cx = 0; cx < chunksx; cx ++){
for(int cy = 0; cy < chunksy; cy ++){
Caches.begin();
for(int tilex = cx*chunksize; tilex < (cx+1)*chunksize; tilex++){
for(int tiley = cy*chunksize; tiley < (cy+1)*chunksize; tiley++){
World.tile(tilex, tiley).floor().drawCache(World.tile(tilex, tiley));
}
}
caches.put(cx, cy, Caches.end());
}
}
}
OrthographicCamera camera = control.camera;
Draw.end();
int crangex = (int)(camera.viewportWidth/(chunksize*tilesize));
int crangey = (int)(camera.viewportHeight/(chunksize*tilesize))+1;
for(int x = -crangex; x <= crangex; x++){
for(int y = -crangey; y <= crangey; y++){
int worldx = Mathf.scl(camera.position.x, chunksize*tilesize) + x;
int worldy = Mathf.scl(camera.position.y, chunksize*tilesize) + y;
if(caches.containsKey(worldx, worldy))
caches.get(worldx, worldy).render();
}
}
Draw.begin();
Draw.reset();
int rangex = control.rangex, rangey = control.rangey;
for(int l = 0; l < 4; l++){
if(l == 1){
if(l == 0){
Draw.surface("shadow");
}
@@ -40,11 +83,11 @@ public class Renderer{
if(Mathf.inBounds(worldx, worldy, tiles)){
Tile tile = tiles[worldx][worldy];
if(l == 1){
if(l == 0){
if(tile.block() != Blocks.air)
Draw.rect("shadow", worldx * tilesize, worldy * tilesize);
}else if(l == 0 || l == 2){
(l == 0 ? tile.floor() : tile.block()).draw(tile);
Draw.rect(tile.block().shadow, worldx * tilesize, worldy * tilesize);
}else if(l == 1){
tile.block().draw(tile);
}else{
tile.block().drawOver(tile);
}
@@ -52,7 +95,7 @@ public class Renderer{
}
}
if(l == 1){
if(l == 0){
Draw.color(0, 0, 0, 0.15f);
Draw.flushSurface();
Draw.color();
@@ -89,16 +132,16 @@ public class Renderer{
else
Cursors.restoreCursor();
Draw.clear();
Draw.reset();
}
//block breaking
if(Inputs.buttonDown(Buttons.RIGHT) && World.cursorNear()){
Tile tile = World.cursorTile();
if(tile.artifical() && tile.block() != ProductionBlocks.core){
Draw.color(Color.YELLOW, Color.SCARLET, breaktime / breakduration);
if(tile.breakable() && tile.block() != ProductionBlocks.core){
Draw.color(Color.YELLOW, Color.SCARLET, breaktime / tile.block().breaktime);
Draw.square(tile.worldx(), tile.worldy(), 4);
Draw.clear();
Draw.reset();
}
}
@@ -148,6 +191,6 @@ public class Renderer{
Draw.color(Color.RED);
if(w >= 1)
Draw.line(x - len + 1, y - offset, x - len + w, y - offset);
Draw.clear();
Draw.reset();
}
}

View File

@@ -1,12 +1,16 @@
package io.anuke.mindustry;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.scene.actions.Actions.*;
import java.util.function.BooleanSupplier;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.entities.Weapon;
@@ -18,8 +22,8 @@ import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Textures;
import io.anuke.ucore.modules.SceneModule;
import io.anuke.ucore.scene.Scene;
import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.builders.*;
import io.anuke.ucore.scene.style.Styles;
import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
@@ -40,7 +44,20 @@ public class UI extends SceneModule{
};
public UI() {
Styles.styles.font().setUseIntegerPositions(false);
Dialog.setShowAction(()->{
return sequence(Actions.moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight(), Align.center),
parallel(Actions.moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2, Align.center, 0.09f, Interpolation.fade),
Actions.fadeIn(0.09f, Interpolation.fade)));
});
Dialog.setHideAction(()->{
return sequence(
parallel(Actions.moveBy(0, -Gdx.graphics.getHeight()/2, 0.08f, Interpolation.fade),
Actions.fadeOut(0.08f, Interpolation.fade)));
});
skin.font().setUseIntegerPositions(false);
TooltipManager.getInstance().animations = false;
Dialog.closePadR = -1;
@@ -59,7 +76,7 @@ public class UI extends SceneModule{
Draw.color(Hue.lightness(0.6f));
int tw = w/64+1;//, th = h/64+1;
int tw = w/64+1;
batch.draw(Textures.get("back"), 0, 0, 0, 0, w, h);
@@ -67,11 +84,6 @@ public class UI extends SceneModule{
batch.draw(Textures.get("conveyort"), x*64, 0, 0, (int)(Timers.time()*2*(x%2-0.5f)), 32, h);
}
//for(int y = 0; y < th; y ++){
// batch.draw(Textures.get("conveyor"), 0, y*64, (int)(Timers.time()*2*(y%2-0.5f)), 0, w, 32);
//}
Draw.color();
Draw.tscl(1.5f);
@@ -173,17 +185,17 @@ public class UI extends SceneModule{
maxcol = Math.max((int)((float)recipes.size/rows+1), maxcol);
}
for(Section sec : Section.values()){
recipes.clear();
Recipe.getBy(sec, recipes);
ImageButton button = new ImageButton("icon-"+sec.name(), "toggle");
add(button).size(size).height(size+8);
add(button).fill().height(54).padTop(-10);
button.getImageCell().size(40).padBottom(4);
group.add(button);
Table table = new Table();
table.pad(4);
int i = 0;
@@ -265,6 +277,9 @@ public class UI extends SceneModule{
add(stack).colspan(3);
get().pad(10f);
get().padLeft(0f);
get().padRight(0f);
end();
}}.right().bottom().uniformX();
@@ -350,28 +365,39 @@ public class UI extends SceneModule{
//menu table
new table(){{
float w = 200;
new table("button"){{
new button("Play", () -> {
levels.show();
}).width(w);
new button("Play", () -> {
levels.show();
}).width(w);
row();
row();
new button("Settings", () -> {
prefs.show(scene);
}).width(w);
new button("Settings", () -> {
prefs.show(scene);
}).width(w);
row();
row();
new button("Controls", () -> {
keys.show(scene);
}).width(w);
new button("Controls", () -> {
keys.show(scene);
}).width(w);
row();
row();
new button("About", () -> {
about.show(scene);
}).width(w);
new button("About", () -> {
about.show(scene);
}).width(w);
row();
if(Gdx.app.getType() != ApplicationType.WebGL)
new button("Exit", () -> {
Gdx.app.exit();
}).width(w);
get().pad(20);
}};
get().setVisible(nplay);
}}.end();

View File

@@ -18,7 +18,6 @@ public class Vars{
public static final float respawnduration = 60*4;
public static final float wavespace = 20*60;
public static final float enemyspawnspace = 65;
public static final float breakduration = 30;
public static boolean debug = false;
public static final Vector2 vector = new Vector2();
@@ -36,7 +35,7 @@ public class Vars{
public static float breaktime = 0;
public static final String[] maps = {"delta", "canyon", "pit", "maze"};
public static final String[] maps = {"delta", "canyon", "pit", "maze", "test"};
public static Pixmap[] mapPixmaps;
public static Texture[] mapTextures;
public static int currentMap;

View File

@@ -28,6 +28,14 @@ public class World{
return tile == null || tile.block().solid;
}
public static int width(){
return Vars.mapPixmaps[Vars.currentMap].getWidth();
}
public static int height(){
return Vars.mapPixmaps[Vars.currentMap].getHeight();
}
public static Tile tile(int x, int y){
if(!Mathf.inBounds(x, y, tiles)) return null;
return tiles[x][y];

View File

@@ -14,8 +14,8 @@ public class MHueristic implements Heuristic<Tile>{
float cost = Math.abs(node.worldx() - other.worldx()) + Math.abs(node.worldy() - other.worldy());
//TODO balance multiplier
if(node.artifical() && node.block().solid) cost += Vars.tilesize*multiplier;
if(other.artifical() && other.block().solid) cost += Vars.tilesize*multiplier;
if(node.breakable() && node.block().solid) cost += Vars.tilesize*multiplier;
if(other.breakable() && other.block().solid) cost += Vars.tilesize*multiplier;
return cost;
}

View File

@@ -13,28 +13,28 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
public void draw(Bullet b){
Draw.color("gray");
Draw.square(b.x, b.y, 1f);
Draw.clear();
Draw.reset();
}
},
iron = new BulletType(1.7f, 2){
public void draw(Bullet b){
Draw.color("gray");
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.clear();
Draw.reset();
}
},
sniper = new BulletType(3f, 20){
public void draw(Bullet b){
Draw.color("lightgray");
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.clear();
Draw.reset();
}
},
small = new BulletType(1.5f, 1){
public void draw(Bullet b){
Draw.color("orange");
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.clear();
Draw.reset();
}
},
smallfast = new BulletType(1.6f, 2){
@@ -42,7 +42,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
public void draw(Bullet b){
Draw.color(color);
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.clear();
Draw.reset();
}
},
flame = new BulletType(0.6f, 4){
@@ -50,7 +50,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Draw.color(Color.YELLOW, Color.SCARLET, b.time/lifetime);
float size = 6f-b.time/lifetime*5f;
Draw.rect("circle", b.x, b.y, size, size);
Draw.clear();
Draw.reset();
}
},
flameshot = new BulletType(0.5f, 3){
@@ -58,7 +58,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
Draw.color(Color.ORANGE, Color.SCARLET, b.time/lifetime);
float size = 6f-b.time/lifetime*5f;
Draw.rect("circle", b.x, b.y, size, size);
Draw.clear();
Draw.reset();
}
},
shot = new BulletType(2.4f, 2){
@@ -66,7 +66,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
public void draw(Bullet b){
Draw.color(Color.GOLD);
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.clear();
Draw.reset();
}
},
shot2 = new BulletType(2.5f, 2){
@@ -74,7 +74,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
public void draw(Bullet b){
Draw.color(Color.SKY);
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.clear();
Draw.reset();
}
};

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.entities;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
@@ -80,6 +81,9 @@ public class Player extends DestructibleEntity{
}else{
float angle = Angles.mouseAngle(x, y);
direction.lerp(vector.set(0, 1).setAngle(angle), 0.26f);
if(MathUtils.isEqual(angle, direction.angle(), 0.05f)){
direction.setAngle(angle);
}
}
}
}

View File

@@ -34,7 +34,7 @@ public class MenuDialog extends Dialog{
hide();
paused = false;
playing = false;
});
}).show();
}).width(200);
}
}

View File

@@ -1,23 +1,38 @@
package io.anuke.mindustry.world;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.World;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.graphics.Caches;
import io.anuke.ucore.util.Mathf;
public class Block{
private static int lastid;
protected static Vector2 vector = new Vector2();
protected static Vector2 vector2 = new Vector2();
protected static TextureRegion temp = new TextureRegion();
public final String name;
public boolean solid, update, rotate;
public boolean solid, update, rotate, breakable;
public int health = 40;
public String shadow = "shadow";
public float breaktime = 30;
public final int id;
//edge fallback, used for ores
public String edge = "stone";
//whether to have 3 variants
public boolean vary = true;
public Block(String name) {
this.name = name;
solid = false;
this.solid = false;
this.id = lastid++;
}
public void drawOver(Tile tile){}
@@ -126,11 +141,48 @@ public class Block{
}
return false;
}
public void drawCache(Tile tile){
MathUtils.random.setSeed(tile.id());
Caches.draw(vary ? (name() + MathUtils.random(1, 3)) : name(), tile.worldx(), tile.worldy());
for(int dx = -1; dx <= 1; dx ++){
for(int dy = -1; dy <= 1; dy ++){
if(dx == 0 && dy == 0) continue;
Tile other = World.tile(tile.x+dx, tile.y+dy);
if(other == null) continue;
Block floor = other.floor();
if(floor.id <= this.id) continue;
TextureRegion region = Draw.region(floor.name() + "edge");
if(region == null)
region = Draw.region(floor.edge + "edge");
int sx = -dx*8+2, sy = -dy*8+2;
int x = Mathf.clamp(sx, 0, 12);
int y = Mathf.clamp(sy, 0, 12);
int w = Mathf.clamp(sx+8, 0, 12)-x, h = Mathf.clamp(sy+8, 0, 12)-y;
float rx = Mathf.clamp(dx*8, 0, 8-w);
float ry = Mathf.clamp(dy*8, 0, 8-h);
temp.setTexture(region.getTexture());
temp.setRegion(region.getRegionX()+x, region.getRegionY()+y+h, w, -h);
Caches.draw(temp, tile.worldx()-4 + rx, tile.worldy()-4 + ry, w, h);
}
}
}
public void draw(Tile tile){
if(tile.floor() == this){
MathUtils.random.setSeed(tile.id());
Draw.rect(name() + MathUtils.random(1, 3), tile.worldx(), tile.worldy(), rotate ? tile.rotation * 90 : 0);
throw new RuntimeException("Rendering non-cached tiles is disabled.");
}else{
Draw.rect(name(), tile.worldx(), tile.worldy(), rotate ? tile.rotation * 90 : 0);
}

View File

@@ -11,6 +11,7 @@ import com.badlogic.gdx.math.MathUtils;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.noise.Noise;
import io.anuke.ucore.util.Mathf;
public class Generator{
static final int stonefloor = Color.rgba8888(Hue.rgb(54, 54, 54));
@@ -34,13 +35,29 @@ public class Generator{
floor = Blocks.iron;
}
if(Noise.nnoise(x, y, 8, 1) > 0.1){
floor = Blocks.grass;
}
if(Noise.nnoise(x, y, 8, 1) > 0.1){
floor = Blocks.water;
}
if(Mathf.chance(0.01)){
block = Blocks.rock;
}
if(Mathf.chance(0.01)){
block = Blocks.rock2;
}
if(Noise.nnoise(x, y, 6, 1) > 0.245){
floor = Blocks.coal;
}
if(color == stone && map == 1){
block = Blocks.dirtblock;
}else if(color == stone){
block = Blocks.stoneblock;
block = Mathf.choose(Blocks.stoneblock, Blocks.stoneblock2, Blocks.stoneblock3);
}else if(color == start){
core = tiles[x][y];
}else if(color == spawn){

View File

@@ -64,8 +64,8 @@ public class Tile{
this.floor = type;
}
public boolean artifical(){
return block.update;
public boolean breakable(){
return block.update || block.breakable;
}
public Tile[] getNearby(){

View File

@@ -21,10 +21,35 @@ public class Blocks{
grass = new Block("grass"),
water = new Block("water"){{
vary = false;
solid = true;
}},
stoneblock = new Block("stoneblock"){{
solid = true;
}},
stoneblock2 = new Block("stoneblock2"){{
solid = true;
}},
stoneblock3 = new Block("stoneblock3"){{
solid = true;
}},
rock = new Block("rock"){{
shadow = "rockshadow";
breakable = true;
breaktime = 10;
}},
rock2 = new Block("rock2"){{
shadow = "rock2shadow";
breakable = true;
breaktime = 10;
}},
dirtblock = new Block("dirtblock"){{
solid = true;
}},

View File

@@ -48,7 +48,7 @@ public class RepairTurret extends Turret{
Draw.line(x, y, x2, y2);
Draw.thickness(1f);
Draw.rect("circle", x2, y2, 5f, 5f);
Draw.clear();
Draw.reset();
}
Draw.rect(name(), tile.worldx(), tile.worldy(), entity.rotation - 90);

View File

@@ -42,7 +42,7 @@ public class Turret extends Block{
public void drawPixelOverlay(Tile tile){
Draw.color("green");
Draw.dashcircle(tile.worldx(), tile.worldy(), range);
Draw.clear();
Draw.reset();
}
@Override