diff --git a/build.gradle b/build.gradle index bb3a6ddfc5..937e43ad8f 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { dependencies { classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6' classpath 'com.android.tools.build:gradle:2.2.0' - classpath 'org.akhikhl.gretty:gretty:+' + //classpath 'org.akhikhl.gretty:gretty:+' } } @@ -80,7 +80,7 @@ project(":core") { dependencies { //compile fileTree(dir: '../core/lib', include: '*.jar') - compile 'com.github.anuken:ucore:b8222ac95e' + compile 'com.github.anuken:ucore:c93833a2b5' compile "com.badlogicgames.gdx:gdx:$gdxVersion" compile "com.badlogicgames.gdx:gdx-ai:1.8.1" } diff --git a/core/src/io/anuke/mindustry/Control.java b/core/src/io/anuke/mindustry/Control.java index c8e79f03f7..86b946b315 100644 --- a/core/src/io/anuke/mindustry/Control.java +++ b/core/src/io/anuke/mindustry/Control.java @@ -62,6 +62,8 @@ public class Control extends RendererModule{ "corexplode.wav", "break.wav", "spawn.wav", "flame.wav", "die.wav", "respawn.wav", "purchase.wav", "flame2.wav"); + Sounds.setFalloff(9000f); + Musics.load("1.mp3", "2.mp3", "3.mp3"); World.loadMaps(); @@ -80,8 +82,6 @@ public class Control extends RendererModule{ for(String map : maps) Settings.defaults("hiscore"+map, 0); - Sounds.setFalloff(9000f); - player = new Player(); } @@ -391,6 +391,12 @@ public class Control extends RendererModule{ Renderer.renderPixelOverlay(); } + @Override + public void dispose(){ + super.dispose(); + World.disposeMaps(); + } + @Override public void resize(int width, int height){ super.resize(width, height); diff --git a/core/src/io/anuke/mindustry/UI.java b/core/src/io/anuke/mindustry/UI.java index 94e473c190..8c8ad8e315 100644 --- a/core/src/io/anuke/mindustry/UI.java +++ b/core/src/io/anuke/mindustry/UI.java @@ -435,10 +435,11 @@ public class UI extends SceneModule{ row(); - if(Gdx.app.getType() != ApplicationType.WebGL) - new button("Exit", () -> { - Gdx.app.exit(); - }); + if(Gdx.app.getType() != ApplicationType.WebGL && !android){ + new button("Exit", () -> { + Gdx.app.exit(); + }); + } get().pad(Unit.dp.inPixels(20)); }}; diff --git a/core/src/io/anuke/mindustry/World.java b/core/src/io/anuke/mindustry/World.java index f640722bcc..601cff27c7 100644 --- a/core/src/io/anuke/mindustry/World.java +++ b/core/src/io/anuke/mindustry/World.java @@ -225,4 +225,14 @@ public class World{ public static int tiley(){ return Mathf.scl2(Graphics.mouseWorld().y, tilesize); } + + public static void disposeMaps(){ + for(Pixmap pixmap : mapPixmaps){ + pixmap.dispose(); + } + + for(Texture texture : mapTextures){ + texture.dispose(); + } + } } diff --git a/core/src/io/anuke/mindustry/ai/MHueristic.java b/core/src/io/anuke/mindustry/ai/MHueristic.java index 48e8aa2ba7..d69b91904f 100644 --- a/core/src/io/anuke/mindustry/ai/MHueristic.java +++ b/core/src/io/anuke/mindustry/ai/MHueristic.java @@ -16,6 +16,11 @@ public class MHueristic implements Heuristic{ //TODO balance multiplier if(node.breakable() && node.block().solid) cost += Vars.tilesize*multiplier; if(other.breakable() && other.block().solid) cost += Vars.tilesize*multiplier; + for(Tile tile : node.getNearby()){ + if(tile != null && tile.solid()){ + cost += Vars.tilesize*2; + } + } return cost; } diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index ef66c49832..52aff09f4b 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -1,20 +1,23 @@ package io.anuke.mindustry.ai; -import com.badlogic.gdx.ai.pfa.DefaultGraphPath; import com.badlogic.gdx.ai.pfa.PathFinder; +import com.badlogic.gdx.ai.pfa.PathSmoother; import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.World; import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.core.Effects; public class Pathfind{ static MHueristic heuristic = new MHueristic(); static PassTileGraph passgraph = new PassTileGraph(); static PathFinder passpathfinder; - static Array> paths = new Array<>(); + static Array paths = new Array<>(); static Tile[][] pathSequences; + static PathSmoother smoother = new PathSmoother(new Raycaster()); static Vector2 vector = new Vector2(); static public Vector2 find(Enemy enemy){ @@ -53,19 +56,21 @@ public class Pathfind{ if(paths.size == 0){ pathSequences = new Tile[World.spawnpoints.size][0]; for(int i = 0; i < World.spawnpoints.size; i ++){ - DefaultGraphPath path = new DefaultGraphPath<>(); + SmoothGraphPath path = new SmoothGraphPath(); paths.add(path); } } for(int i = 0; i < paths.size; i ++){ - DefaultGraphPath path = paths.get(i); + SmoothGraphPath path = paths.get(i); path.clear(); passpathfinder.searchNodePath( World.spawnpoints.get(i), World.core, heuristic, path); + smoother.smoothPath(path); + pathSequences[i] = new Tile[path.getCount()]; for(int node = 0; node < path.getCount(); node ++){ @@ -75,10 +80,10 @@ public class Pathfind{ } - //if(debug) - //for(Tile tile : path){ - // Effects.effect("ind", tile.worldx(), tile.worldy()); - //} + if(Vars.debug) + for(Tile tile : path){ + Effects.effect("ind", tile.worldx(), tile.worldy()); + } } } diff --git a/core/src/io/anuke/mindustry/ai/Raycaster.java b/core/src/io/anuke/mindustry/ai/Raycaster.java new file mode 100644 index 0000000000..1f05aeff55 --- /dev/null +++ b/core/src/io/anuke/mindustry/ai/Raycaster.java @@ -0,0 +1,86 @@ +package io.anuke.mindustry.ai; + +import com.badlogic.gdx.ai.utils.Collision; +import com.badlogic.gdx.ai.utils.Ray; +import com.badlogic.gdx.ai.utils.RaycastCollisionDetector; +import com.badlogic.gdx.math.Vector2; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.World; +import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Mathf; + +public class Raycaster implements RaycastCollisionDetector{ + private boolean found = false; + + @Override + public boolean collides(Ray ray){ + found = false; + + Geometry.iterateLine(0f, ray.start.x, ray.start.y, ray.end.x, ray.end.y, Vars.tilesize, (x, y)->{ + if(solid(x, y)){ + found = true; + return; + } + }); + + return found; + } + + @Override + public boolean findCollision(Collision collision, Ray ray){ + Vector2 v = vectorCast(ray.start.x, ray.start.y, ray.end.x, ray.end.y); + if(v == null) return false; + collision.point = v; + collision.normal = v.nor(); + return true; + } + + Vector2 vectorCast(float x0f, float y0f, float x1f, float y1f){ + int x0 = (int)x0f; + int y0 = (int)y0f; + int x1 = (int)x1f; + int y1 = (int)y1f; + int dx = Math.abs(x1 - x0); + int dy = Math.abs(y1 - y0); + + int sx = x0 < x1 ? 1 : -1; + int sy = y0 < y1 ? 1 : -1; + + int err = dx - dy; + int e2; + while(true){ + + if(solid(x0, y0)){ + return new Vector2(x0, y0); + } + if(x0 == x1 && y0 == y1) break; + + e2 = 2 * err; + if(e2 > -dy){ + err = err - dy; + x0 = x0 + sx; + } + + if(e2 < dx){ + err = err + dx; + y0 = y0 + sy; + } + } + return null; + } + + private boolean solid(float x, float y){ + Tile tile = World.tile(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize)); + + if(tile == null || tile.solid()) return true; + + for(Tile near : tile.getNearby()){ + if(near == null || near.solid()) return true; + } + + return false; + } + +} diff --git a/core/src/io/anuke/mindustry/ai/SmoothGraphPath.java b/core/src/io/anuke/mindustry/ai/SmoothGraphPath.java new file mode 100644 index 0000000000..5d3bbc56c2 --- /dev/null +++ b/core/src/io/anuke/mindustry/ai/SmoothGraphPath.java @@ -0,0 +1,28 @@ +package io.anuke.mindustry.ai; + +import com.badlogic.gdx.ai.pfa.DefaultGraphPath; +import com.badlogic.gdx.ai.pfa.SmoothableGraphPath; +import com.badlogic.gdx.math.Vector2; + +import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.util.Tmp; + +public class SmoothGraphPath extends DefaultGraphPath implements SmoothableGraphPath{ + + @Override + public Vector2 getNodePosition(int index){ + Tile tile = nodes.get(index); + return Tmp.v1.set(tile.worldx(), tile.worldy()); + } + + @Override + public void swapNodes(int index1, int index2){ + nodes.swap(index1, index2); + } + + @Override + public void truncatePath(int newLength){ + nodes.truncate(newLength); + } + +} diff --git a/html/build.gradle b/html/build.gradle index ad8a76d92e..29f2f9b23c 100644 --- a/html/build.gradle +++ b/html/build.gradle @@ -1,5 +1,6 @@ apply plugin: "java" -apply plugin: 'org.akhikhl.gretty' +apply plugin: "jetty" +//apply plugin: 'org.akhikhl.gretty' gwt { gwtVersion='2.8.0' // Should match the gwt version used for building the gwt backend