Okay may sound like a dumb question to ask, however I am not completely sure how i would make an entity follow the path and make this optimized without having to calculate everything frame
This is what i currently have
private int currentPath = 0;
@Override
public void update(float delta) {
super.update(delta);
if (path == null) {
currentPath = 0;
recalculatePath();
}
if(path.size > 0 && currentPath+1 < path.size){
int pathX = path.get(currentPath);
int pathY = path.get(currentPath+1);
if (currentTileX < pathX) {
getVelocity().x = movementSpeed;
} else if (currentTileX > pathX) {
getVelocity().x = -movementSpeed;
} else {
getVelocity().x = 0;
}
if (currentTileY < pathY) {
getVelocity().y = movementSpeed;
} else if (currentTileY > pathY) {
getVelocity().y = -movementSpeed;
} else {
getVelocity().y = 0;
}
if(currentTileX == pathX && currentTileY == pathY){
System.out.println(11);
currentPath+=2;
}
translate(delta * getVelocity().x, delta * getVelocity().y);
}else{
currentPath = 0;
recalculatePath();
}
}
private void recalculatePath() {
IntArray calculatedPath = pathFinder.getAstar().getPath(currentTileX, currentTileY, target.getCurrentTileX(), target.getCurrentTileY());
if(path == null){
path = new IntArray();
}else{
path.clear();
}
while(calculatedPath.size > 0){
int y = calculatedPath.pop();
int x = calculatedPath.pop();
path.add(x);
path.add(y);
}
}
@Override
public void render(SpriteBatch worldBatch) {
super.render(worldBatch);
// IntArray path = pathFinder.getAstar().getPath(getCurrentTileX(), getCurrentTileY(), target.getCurrentTileX(), target.getCurrentTileY());
//
for (int i = 0, n = path.size; i < n; i += 2) {
int pathX = path.get(i);
int pathY = path.get(i+1);
worldBatch.draw(getTexture(), pathX*MasterTile.TILE_WIDTH, pathY * MasterTile.TILE_HEIGHT
, getWidth() / 2, getHeight() / 2, getWidth(), getHeight(), 1f, 1f, getRotation());
}
}
}
The problem with this though is that the entity seems to be going through walls and when i enable collision it gets stuck??
Collision code
package com.hawk.linear.engine.collisioin;
import com.badlogic.gdx.math.Vector2;
import com.hawk.linear.engine.entity.Entity;
import com.hawk.linear.engine.map.TileMap;
import com.hawk.linear.engine.renderer.TileRenderer;
import com.hawk.linear.engine.tile.MasterTile;
import com.hawk.linear.engine.tile.Tile;
import com.hawk.linear.engine.tile.tiles.AirTile;
import com.hawk.linear.engine.tile.tiles.BlockType;
public class CollisionTileEngine {
/**
* This is the collision engine for tiles the EXCEPTION_LIST is a list of tile ids on which ones don't use collision
*/
private static int[] EXCEPTION_LIST = { BlockType.BFLOWER, BlockType.RFLOWER, BlockType.PIFLOWER, BlockType.PUFLOWER, BlockType.TORCH };
/**
* An entity will use this to have collision on the world (TileRenderer)
*
* @param e
* is the entity which you are checking the collision for
* @param oldX
* is the old position x (before the translate has happened)
* @param oldY
* is the old position y (before the translate has happened)
*/
public static void applyCollision(Entity e, float oldX, float oldY) {
// It works by getting the entitys position and then changing that to the tile position
// for example an entity which has a position of x = 250 y = 500 now each tile has a size of 50 so we divide
// x/tileSizeX and y/tieSizeY
// then cast it into a integer because [][] (multidimensional arrays) can only take a integer
// we then get the top,bottom,left,right tile using the TileMap data which
// is a multidimensional array and work how if the entity is colliding with it
// that is the simple version
boolean collisionX = false;
boolean collisionY = false;
TileMap map = TileRenderer.map;
Vector2 velocity = e.getVelocity();
float x = e.getX();
float y = e.getY();
float w = e.getWidth();
float h = e.getHeight();
float offsetX = 15;
float offsetY = 0;
float offsetXW = 15;
float offsetYH = 20;
if (x / MasterTile.TILE_WIDTH >= 0 && x / MasterTile.TILE_WIDTH <= map.getWidth() - 1 && y / MasterTile.TILE_HEIGHT >= 0 && y / MasterTile.TILE_HEIGHT <= map.getHeight() - 1) {
if (velocity.x < 0) {
// Bottom left
collisionX = checkCollisionTile(e.getX() + offsetX, e.getY() + offsetY, map);
// Middle left
collisionX |= checkCollisionTile(e.getX() + offsetX, (e.getY() + offsetY) + ((h - (offsetYH * 2)) / 2), map);
// Top left
collisionX |= checkCollisionTile(e.getX() + offsetX, (e.getY() + offsetY) + (h - (offsetYH * 2)), map);
} else if (velocity.x > 0) {
// Bottom right
collisionX = checkCollisionTile((e.getX() + offsetX) + (w - (offsetXW * 2)), e.getY() + offsetY, map);
// Middle right
collisionX |= checkCollisionTile(e.getX() + offsetX + (w - (offsetXW * 2)), (e.getY() + offsetY) + ((h - (offsetYH * 2)) / 2), map);
// Top right
collisionX |= checkCollisionTile(e.getX() + offsetX + (w - (offsetXW * 2)), (e.getY() + offsetY) + (h - (offsetYH * 2)), map);
}
if (collisionX) {
e.setX(oldX);
}
if (velocity.y < 0) {
// Bottom left
collisionY = checkCollisionTile(e.getX() + offsetX, e.getY() + offsetY, map);
// Bottom middle
collisionY |= checkCollisionTile(e.getX() + offsetX + ((w - (offsetXW * 2)) / 2), e.getY() + offsetY, map);
// Bottom right
collisionY |= checkCollisionTile(e.getX() + offsetX + (w - (offsetXW * 2)), e.getY() + offsetY, map);
} else if (velocity.y > 0) {
// Top left
collisionY = checkCollisionTile(e.getX() + offsetX, (e.getY() + offsetY) + (h - (offsetYH * 2)), map);
// Top middle
collisionY |= checkCollisionTile(e.getX() + offsetX + ((w - (offsetXW * 2)) / 2), (e.getY() + offsetY) + (h - (offsetYH * 2)), map);
// Top right
collisionY |= checkCollisionTile(e.getX() + offsetX + (w - (offsetXW * 2)), (e.getY() + offsetY) + (h - (offsetYH * 2)), map);
}
if (collisionY) {
e.setY(oldY);
}
if (collisionX) {
e.getVelocity().x = 0;
}
if (collisionY) {
e.getVelocity().y = 0;
}
}
}
/**
* This method checks each individual tile for collision on (TOP layer) by checking it using the EXCEPTION_LIST
*
* @param x
* @param y
* @param tileMap
* @return
*/
public static boolean checkCollisionTile(float x, float y, TileMap tileMap) {
int currentX = (int) (x / MasterTile.TILE_WIDTH);
int currentY = (int) (y / MasterTile.TILE_HEIGHT);
return CollisionTileEngine.checkCollisionTile(currentX, currentY, tileMap);
}
public static boolean checkCollisionTile(int x, int y, TileMap tileMap) {
int currentX = x;
int currentY = y;
if (currentX < 0 || currentX > tileMap.getWidth() - 1 || currentY < 0 || currentY > tileMap.getHeight() - 1) {
return true;
}
Tile topTile = tileMap.getMapData()[currentX][currentY].getTopTile();
if (topTile != null) {
if (topTile instanceof AirTile == false) {
for (int i = 0; i < EXCEPTION_LIST.length; i++) {
int id = EXCEPTION_LIST[i];
if (topTile.getID() == id)
return false;
}
return true;
}
}
return false;
}
}