Changed pathfinding algorithm slightly, added debugging for paths

This commit is contained in:
Anuken
2017-12-08 19:59:04 -05:00
parent cffb673bae
commit 404ec68570
14 changed files with 91 additions and 25 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -30,6 +30,6 @@ void main() {
if(any){ if(any){
gl_FragColor = u_color; gl_FragColor = u_color;
}else{ }else{
gl_FragColor = texture2D(u_texture, T); gl_FragColor = texture2D(u_texture, T) * v_color;
} }
} }

View File

@@ -46,6 +46,8 @@ public class Vars{
public static boolean infiniteAmmo = false; public static boolean infiniteAmmo = false;
//whether to show paths of enemies //whether to show paths of enemies
public static boolean showPaths = true; public static boolean showPaths = true;
//if false, player is always hidden
public static boolean showPlayer = true;
//number of save slots-- increasing may lead to layout issues //number of save slots-- increasing may lead to layout issues
//TODO named save slots, possibly with a scroll dialog //TODO named save slots, possibly with a scroll dialog
public static final int saveSlots = 8; public static final int saveSlots = 8;

View File

@@ -10,7 +10,9 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.world.SpawnPoint; import io.anuke.mindustry.world.SpawnPoint;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
public class Pathfind{ public class Pathfind{
@@ -30,7 +32,6 @@ public class Pathfind{
return vector.set(enemy.x, enemy.y); return vector.set(enemy.x, enemy.y);
}else if(enemy.node == -2){ }else if(enemy.node == -2){
enemy.node = -1; enemy.node = -1;
enemy.findClosestNode();
} }
Tile[] path = enemy.path; Tile[] path = enemy.path;
@@ -43,7 +44,7 @@ public class Pathfind{
if(enemy.node > 1) if(enemy.node > 1)
enemy.node = enemy.node - 1; enemy.node = enemy.node - 1;
}else{ }else{
//what's the problem, then? //must be blocked by a playermade block
} }
enemy.idletime = 0; enemy.idletime = 0;
@@ -100,6 +101,7 @@ public class Pathfind{
if(point.finder.search(point.request, ms * 2)){ if(point.finder.search(point.request, ms * 2)){
smoother.smoothPath(point.path); smoother.smoothPath(point.path);
point.pathTiles = point.path.nodes.toArray(Tile.class); point.pathTiles = point.path.nodes.toArray(Tile.class);
point.tempTiles = point.path.nodes.toArray(Tile.class);
} }
} }
} }
@@ -112,6 +114,7 @@ public class Pathfind{
point.path.clear(); point.path.clear();
point.pathTiles = null; point.pathTiles = null;
point.tempTiles = null;
point.request = new PathFinderRequest<Tile>(point.start, Vars.control.getCore(), heuristic, point.path); point.request = new PathFinderRequest<Tile>(point.start, Vars.control.getCore(), heuristic, point.path);
point.request.statusChanged = true; //IMPORTANT! point.request.statusChanged = true; //IMPORTANT!
@@ -128,22 +131,44 @@ public class Pathfind{
} }
enemy.path = Vars.control.getSpawnPoints().get(enemy.spawn).pathTiles; enemy.path = Vars.control.getSpawnPoints().get(enemy.spawn).pathTiles;
Tile[] path = enemy.path;
Tile closest = null; int closest = findClosest(enemy.path, 0, enemy.x, enemy.y);
float ldst = 0f; closest = findClosest(enemy.path, closest + 1, enemy.x, enemy.y);
//closest ++;
closest = Mathf.clamp(closest, 1, enemy.path.length-1);
Tile end = enemy.path[closest];
enemy.node = closest;
//if the enemy can't get to this node, teleport to it
if(enemy.node < enemy.path.length - 2 && Vars.world.raycastWorld(enemy.x, enemy.y, end.worldx(), end.worldy()) != null){
Timers.run(Mathf.random(20f), () -> enemy.set(end.worldx(), end.worldy()));
}
}
private static int findClosest(Tile[] tiles, int offset, float x, float y){
int cindex = -1; int cindex = -1;
float dst = Float.MAX_VALUE;
for(int i = 0; i < path.length; i ++){ for(int i = offset; i < tiles.length; i ++){
Tile tile = path[i]; Tile tile = tiles[i];
float dst = Vector2.dst(tile.worldx(), tile.worldy(), enemy.x, enemy.y); if(Vector2.dst(tile.worldx(), tile.worldy(), x, y) < dst){
dst = Vector2.dst(tile.worldx(), tile.worldy(), x, y);
if(closest == null || dst < ldst){
ldst = dst;
closest = tile;
cindex = i; cindex = i;
} }
} }
enemy.node = Math.max(cindex, 1);
return cindex;
}
private static int indexOf(Tile tile, Tile[] tiles){
int i = -1;
for(int j = 0; j < tiles.length; j ++){
if(tiles[j] == tile){
return j;
}
}
return i;
} }
private static boolean onLine(Vector2 vector, float x1, float y1, float x2, float y2){ private static boolean onLine(Vector2 vector, float x1, float y1, float x2, float y2){

View File

@@ -270,6 +270,11 @@ public class Renderer extends RendererModule{
Graphics.begin(); Graphics.begin();
Draw.reset(); Draw.reset();
if(Vars.showPaths){
drawPaths();
}
int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2) + 2; int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2) + 2;
int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2) + 2; int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2) + 2;
@@ -384,6 +389,20 @@ public class Renderer extends RendererModule{
cbatch = new CacheBatch(256 * 256 * 3); cbatch = new CacheBatch(256 * 256 * 3);
} }
void drawPaths(){
Draw.color(Color.RED);
for(SpawnPoint point : control.spawnpoints){
if(point.pathTiles != null){
for(int i = 1; i < point.pathTiles.length; i ++){
Draw.line(point.pathTiles[i-1].worldx(), point.pathTiles[i-1].worldy(),
point.pathTiles[i].worldx(), point.pathTiles[i].worldy());
Draw.circle(point.pathTiles[i-1].worldx(), point.pathTiles[i-1].worldy(), 6f);
}
}
}
Draw.reset();
}
void renderPixelOverlay(){ void renderPixelOverlay(){
//draw tutorial placement point //draw tutorial placement point
@@ -503,7 +522,7 @@ public class Renderer extends RendererModule{
drawHealth(entity); drawHealth(entity);
} }
if(!Vars.android) if(!Vars.android && Vars.showPlayer)
drawHealth(player); drawHealth(player);
} }

View File

@@ -112,10 +112,10 @@ public class UI extends SceneModule{
Draw.color(); Draw.color();
TextureRegion back = Draw.region("background"); TextureRegion back = Draw.region("background");
float backscl = 4f; float backscl = 4.5f;
Draw.alpha(0.8f); Draw.alpha(0.7f);
Core.batch.draw(back, w/2 - back.getRegionWidth()*backscl/2, h/2 - back.getRegionHeight()*backscl/2, Core.batch.draw(back, w/2 - back.getRegionWidth()*backscl/2 +240f, h/2 - back.getRegionHeight()*backscl/2 + 250f,
back.getRegionWidth()*backscl, back.getRegionHeight()*backscl); back.getRegionWidth()*backscl, back.getRegionHeight()*backscl);
float logoscl = (int)Unit.dp.inPixels(7); float logoscl = (int)Unit.dp.inPixels(7);

View File

@@ -56,6 +56,8 @@ public class Player extends DestructibleEntity{
@Override @Override
public void draw(){ public void draw(){
if(!Vars.showPlayer) return;
if(Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){ if(Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){
Draw.rect("mech-"+mech.name(), (int)x, (int)y, direction.angle()-90); Draw.rect("mech-"+mech.name(), (int)x, (int)y, direction.angle()-90);
}else{ }else{

View File

@@ -18,7 +18,7 @@ import io.anuke.ucore.util.Tmp;
public class Enemy extends DestructibleEntity{ public class Enemy extends DestructibleEntity{
public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") }; public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") };
public final static int maxtier = 4; public final static int maxtier = 4;
public final static float maxIdle = 60*3f; public final static float maxIdle = 60*1.5f;
protected float speed = 0.4f; protected float speed = 0.4f;
protected float reload = 32; protected float reload = 32;
@@ -143,10 +143,15 @@ public class Enemy extends DestructibleEntity{
out.damage = (int) (damage * Vars.multiplier); out.damage = (int) (damage * Vars.multiplier);
} }
/*
public void findClosestNode(){ public void findClosestNode(){
int index = 0; int index = 0;
int cindex = -1; int cindex = -1;
float dst = Float.MAX_VALUE; float dst = Float.MAX_VALUE;
UCore.log("Finding closest.");
Tile[] clone = path.clone();
UCore.log(clone.length);
//find closest node index //find closest node index
for(Tile tile : path){ for(Tile tile : path){
@@ -171,7 +176,7 @@ public class Enemy extends DestructibleEntity{
set(x2 * Vars.tilesize, y2 * Vars.tilesize); set(x2 * Vars.tilesize, y2 * Vars.tilesize);
}); });
} }
} }*/
@Override @Override
public void added(){ public void added(){
@@ -221,7 +226,7 @@ public class Enemy extends DestructibleEntity{
xvelocity = (x - lastx) / Timers.delta(); xvelocity = (x - lastx) / Timers.delta();
yvelocity = (y - lasty) / Timers.delta(); yvelocity = (y - lasty) / Timers.delta();
float minv = 0.001f; float minv = 0.0001f;
if(xvelocity < minv && yvelocity < minv && node > 0){ if(xvelocity < minv && yvelocity < minv && node > 0){
idletime += Timers.delta(); idletime += Timers.delta();
@@ -248,6 +253,12 @@ public class Enemy extends DestructibleEntity{
Draw.color(); Draw.color();
Draw.rect(region, x, y, this.angle - 90); Draw.rect(region, x, y, this.angle - 90);
if(Vars.showPaths){
Draw.color(Color.PURPLE);
Draw.line(x, y, x + xvelocity*10f, y + yvelocity*10f);
Draw.color();
}
Graphics.flush(); Graphics.flush();
} }

View File

@@ -21,7 +21,7 @@ public class MindustrySettingsDialog extends SettingsDialog{
content().remove(); content().remove();
buttons().remove(); buttons().remove();
ScrollPane pane = new ScrollPane(content()); ScrollPane pane = new ScrollPane(content(), "clear");
pane.setFadeScrollBars(false); pane.setFadeScrollBars(false);
row(); row();

View File

@@ -8,6 +8,7 @@ import io.anuke.mindustry.ai.SmoothGraphPath;
public class SpawnPoint{ public class SpawnPoint{
public Tile start; public Tile start;
public Tile[] pathTiles; public Tile[] pathTiles;
public Tile[] tempTiles;
public PathFinder<Tile> finder; public PathFinder<Tile> finder;
public SmoothGraphPath path = new SmoothGraphPath(); public SmoothGraphPath path = new SmoothGraphPath();
public PathFinderRequest<Tile> request; public PathFinderRequest<Tile> request;

View File

@@ -68,6 +68,12 @@ public class World extends Module{
return tile == null || tile.solid(); return tile == null || tile.solid();
} }
public boolean passable(int x, int y){
Tile tile = tile(x, y);
return tile != null && tile.passable();
}
public boolean wallSolid(int x, int y){ public boolean wallSolid(int x, int y){
Tile tile = tile(x, y); Tile tile = tile(x, y);
return tile == null || tile.block().solid; return tile == null || tile.block().solid;
@@ -462,7 +468,7 @@ public class World extends Module{
int e2; int e2;
while(true){ while(true){
if(solid(x0, y0)){ if(!passable(x0, y0)){
return Tmp.g1.set(x0, y0); return Tmp.g1.set(x0, y0);
} }
if(x0 == x1 && y0 == y1) break; if(x0 == x1 && y0 == y1) break;

Binary file not shown.

Binary file not shown.

Binary file not shown.