mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-02-22 12:38:12 +07:00
Implemented ray-casting-based movement for touchpad controls
Implemented ray-casting-based movement for touchpad controls Works great in open spaces, some issues with wall detection and following
This commit is contained in:
parent
d480d2566b
commit
3e9f0a9d29
@ -263,17 +263,24 @@ public class Entity {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPath(Map map, Vector3 dst) {
|
||||
setPath(map, dst, -1);
|
||||
public boolean setPath(Map map, Vector3 dst) {
|
||||
return setPath(map, dst, -1);
|
||||
}
|
||||
|
||||
public boolean setPath(Map map, Vector3 dst, int maxSteps) {
|
||||
if (dst == null) {
|
||||
path.clear();
|
||||
targets = Collections.emptyIterator();
|
||||
target.set(position);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setPath(Map map, Vector3 dst, int maxSteps) {
|
||||
boolean success = map.findPath(position, dst, path);
|
||||
if (!success) return;
|
||||
if (!success) return false;
|
||||
if (maxSteps != -1 && path.getCount() > maxSteps) {
|
||||
path.clear();
|
||||
targets = Collections.emptyIterator();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DEBUG_PATH) Gdx.app.debug(TAG, "path=" + path);
|
||||
@ -288,6 +295,7 @@ public class Entity {
|
||||
}
|
||||
|
||||
//if (DEBUG_TARGET) Gdx.app.debug(TAG, "target=" + target);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void update(float delta) {
|
||||
|
@ -6,6 +6,8 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ai.pfa.GraphPath;
|
||||
import com.badlogic.gdx.ai.pfa.SmoothableGraphPath;
|
||||
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
|
||||
import com.badlogic.gdx.ai.utils.Collision;
|
||||
import com.badlogic.gdx.ai.utils.Ray;
|
||||
import com.badlogic.gdx.assets.AssetDescriptor;
|
||||
import com.badlogic.gdx.assets.AssetManager;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
@ -559,6 +561,10 @@ public class Map implements Disposable {
|
||||
mapGraph.smoothPath(path);
|
||||
}
|
||||
|
||||
public boolean castRay(Collision<Vector2> dst, Ray<Vector2> ray) {
|
||||
return mapGraph.rayCaster.findCollision(dst, ray);
|
||||
}
|
||||
|
||||
static class Zone {
|
||||
static final Array<Entity> EMPTY_ARRAY = new Array<>(0);
|
||||
|
||||
|
@ -28,11 +28,13 @@ public class MapGraph implements IndexedGraph<MapGraph.Point2> {
|
||||
|
||||
Map map;
|
||||
IntMap<Point2> points = new IntMap<>();
|
||||
MapRaycastCollisionDetector rayCaster;
|
||||
PathSmoother<Point2, Vector2> pathSmoother;
|
||||
|
||||
public MapGraph(Map map) {
|
||||
this.map = map;
|
||||
pathSmoother = new PathSmoother<>(new MapRaycastCollisionDetector(this));
|
||||
rayCaster = new MapRaycastCollisionDetector(this);
|
||||
pathSmoother = new PathSmoother<>(rayCaster);
|
||||
}
|
||||
|
||||
public GraphPath<Point2> path(Vector3 src, Vector3 dst, GraphPath<Point2> path) {
|
||||
@ -294,8 +296,65 @@ public class MapGraph implements IndexedGraph<MapGraph.Point2> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean findCollision(Collision<Vector2> outputCollision, Ray<Vector2> inputRay) {
|
||||
throw new UnsupportedOperationException();
|
||||
public boolean findCollision(Collision<Vector2> dst, Ray<Vector2> ray) {
|
||||
int x0 = (int) ray.start.x;
|
||||
int y0 = (int) ray.start.y;
|
||||
int x1 = (int) ray.end.x;
|
||||
int y1 = (int) ray.end.y;
|
||||
|
||||
int tmp;
|
||||
boolean steep = Math.abs(y1 - y0) > Math.abs(x1 - x0);
|
||||
if (steep) {
|
||||
// Swap x0 and y0
|
||||
tmp = x0;
|
||||
x0 = y0;
|
||||
y0 = tmp;
|
||||
// Swap x1 and y1
|
||||
tmp = x1;
|
||||
x1 = y1;
|
||||
y1 = tmp;
|
||||
}
|
||||
if (x0 > x1) {
|
||||
// Swap x0 and x1
|
||||
tmp = x0;
|
||||
x0 = x1;
|
||||
x1 = tmp;
|
||||
// Swap y0 and y1
|
||||
tmp = y0;
|
||||
y0 = y1;
|
||||
y1 = tmp;
|
||||
}
|
||||
|
||||
int deltax = x1 - x0;
|
||||
int deltay = Math.abs(y1 - y0);
|
||||
int error = 0;
|
||||
int y = y0;
|
||||
int ystep = (y0 < y1 ? 1 : -1);
|
||||
dst.point.set(steep ? y0 : x0, steep ? x0 : y0);
|
||||
//dst.normal.setZero();
|
||||
for (int x = x0; x <= x1; x++) {
|
||||
if (steep) {
|
||||
Map.Zone zone = map.getZone(y, x);
|
||||
if (zone == null || zone.flags(y, x) != 0) {
|
||||
//dst.normal.set(y, x);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
Map.Zone zone = map.getZone(x, y);
|
||||
if (zone == null || zone.flags(x, y) != 0) {
|
||||
//dst.normal.set(x, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dst.point.set(steep ? y : x, steep ? x : y);
|
||||
error += deltay;
|
||||
if (error + error >= deltax) {
|
||||
y += ystep;
|
||||
error -= deltax;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,14 @@ import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.InputAdapter;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.ai.utils.Collision;
|
||||
import com.badlogic.gdx.ai.utils.Ray;
|
||||
import com.badlogic.gdx.assets.AssetDescriptor;
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.net.Socket;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
@ -34,13 +36,13 @@ import java.io.PrintWriter;
|
||||
|
||||
import gdx.diablo.Diablo;
|
||||
import gdx.diablo.Keys;
|
||||
import gdx.diablo.entity.Direction;
|
||||
import gdx.diablo.entity.Entity;
|
||||
import gdx.diablo.entity.Player;
|
||||
import gdx.diablo.graphics.PaletteIndexedBatch;
|
||||
import gdx.diablo.graphics.PaletteIndexedColorDrawable;
|
||||
import gdx.diablo.key.MappedKey;
|
||||
import gdx.diablo.key.MappedKeyStateAdapter;
|
||||
import gdx.diablo.map.DT1;
|
||||
import gdx.diablo.map.Map;
|
||||
import gdx.diablo.map.MapLoader;
|
||||
import gdx.diablo.map.MapRenderer;
|
||||
@ -368,10 +370,50 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
||||
if (x == 0 && y == 0) {
|
||||
player.setPath(map, null);
|
||||
} else {
|
||||
//float rad = MathUtils.atan2(y, x);
|
||||
//x = Direction.getOffX(rad);
|
||||
//y = Direction.getOffY(rad);
|
||||
//player.setPath(map, new Vector3(x, y, 0).add(player.position()), 3);
|
||||
|
||||
Vector2 position = new Vector2(player.position().x, player.position().y);
|
||||
Vector2 target = new Vector2(x, y).scl(DT1.Tile.WIDTH).add(mapRenderer.project(position.x, position.y, new Vector2()));
|
||||
GridPoint2 coords = mapRenderer.coords(target.x, target.y, new GridPoint2());
|
||||
target.set(coords.x, coords.y);
|
||||
Ray<Vector2> ray = new Ray<>(position, target);
|
||||
Collision<Vector2> collision = new Collision<>(new Vector2(), new Vector2());
|
||||
boolean hit = map.castRay(collision, ray);
|
||||
if (hit) {
|
||||
if (position.epsilonEquals(collision.point, 1.0f)) {
|
||||
/*System.out.println("against wall");
|
||||
|
||||
float rad = MathUtils.atan2(y, x);
|
||||
x = Direction.getOffX(rad);
|
||||
y = Direction.getOffY(rad);
|
||||
player.setPath(map, new Vector3(x, y, 0).add(player.position()), 3);
|
||||
if (rad > MathUtils.PI - 0.46365f) {
|
||||
rad -= MathUtils.PI - 0.46365f;
|
||||
System.out.println("1 " + rad);
|
||||
} else if (rad < -0.46365f) {
|
||||
rad += MathUtils.PI + 0.46365f;
|
||||
System.out.println("2 " + rad);
|
||||
}
|
||||
|
||||
if (rad > 2.0944f) {
|
||||
Vector3 newTarget = new Vector3(player.position()).add(1, 0, 0);
|
||||
player.setPath(map, newTarget, 2);
|
||||
System.out.println("down " + player.position() + "; " + newTarget);
|
||||
} else if (rad > 0 && rad < 1.0472f) {
|
||||
Vector3 newTarget = new Vector3(player.position()).add(-1, 0, 0);
|
||||
player.setPath(map, newTarget, 2);
|
||||
System.out.println("up " + player.position() + "; " + newTarget);
|
||||
}*/
|
||||
} else {
|
||||
//System.out.println("headed for wall " + position + ", " + collision.point);
|
||||
player.setPath(map, new Vector3(collision.point, 0), 3);
|
||||
}
|
||||
} else {
|
||||
//System.out.println("freedom baby");
|
||||
player.target().set(target, 0);
|
||||
}
|
||||
|
||||
//System.out.println("hit " + hit + "; " + collision.point + "; " + collision.normal);
|
||||
}
|
||||
} else {
|
||||
if (Gdx.input.isButtonPressed(Input.Buttons.LEFT)) {
|
||||
|
Loading…
Reference in New Issue
Block a user