How to check tile in front of player

I’m working on my pacman game now, i’ve got it setup to detect which tiles are suppose to be blocked which ive added to an array list. I’m using ShapeRenderer to show which tiles are blocked and which aren’t…Now i’m having trouble deciding which tile is in front of the player to see if it’s blockable…

This is my map class


package com.psillidev.pacman1;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;

public class Map {
TiledMap tiledMap;
public TiledMapTileLayer layer;
int[] tileLayer = {0} ;
int[] collisionLayer;

Cell tileCell;

Array<Rectangle> blockedTiles = new Array<Rectangle>();

public OrthogonalTiledMapRenderer renderer;
float unitScale;

	public Map() {
		float unitScale = 1/16f;
		
		tiledMap = new TmxMapLoader().load("data/pactest.tmx");
		
		layer = (TiledMapTileLayer) tiledMap.getLayers().get(1);
		renderer = new OrthogonalTiledMapRenderer(tiledMap, 1/16f);
		
		setBlockedTiles();
	}
	
	void setBlockedTiles() {
		for (int y = 0;y < layer.getHeight();y++ ) {
			for (int x = 0; x < layer.getWidth();x++) {
				Cell cell = layer.getCell(x, y);
				if (layer.getCell(x,y)!=null) {
				Rectangle tempRect = new Rectangle(x*16,y*16,16,16);
				
				
				
				blockedTiles.add(tempRect);
				
				//System.out.println(blockedTiles.size);
				
				if (layer.getCell(x, y)==null) continue;
				
				}
			}
				
		}
	
	}
	
	public TiledMap getMap() {
		return tiledMap;
	}
	
	public float getScale() {
		return unitScale;
	}
	
	public Cell getCell(int x, int y) {
		return layer.getCell(x, y);
	}
	
	public Array<Rectangle> getBlockedTiles() {
		return blockedTiles;
	}
	
	public TiledMapTileLayer getLayer() {
		return layer;
	}
	
	public void render(OrthographicCamera camera) {
		renderer.setView(camera);
		//renderer.renderTileLayer(layer);
		//renderer.render();
		renderer.render(tileLayer);
		
		System.out.println(blockedTiles.size);
		
		ShapeRenderer rend = new ShapeRenderer(); 
		rend.begin(ShapeType.Line);
		for (int t = 0;t < blockedTiles.size;t++) {
		rend.rect(blockedTiles.get(t).x, blockedTiles.get(t).y, blockedTiles.get(t).width, blockedTiles.get(t).height); 
		System.out.println("Tile: " + t + " X: " + blockedTiles.get(t).x + " Y: " + blockedTiles.get(t).y + " Width: " + blockedTiles.get(t).width + " Height: " + blockedTiles.get(t).height);
		}
		rend.end();
		
	}
	
}

This is my player class where i’m moving the pacman…


public void move(Map map) {
		
		//for (int b = 0;b < map.getBlockedTiles().size;b++) {
		//	Rectangle tempRect = map.getBlockedTiles().get(b);
		if (direction == 0) {
			
			setY(getY() + (int)(Gdx.graphics.getDeltaTime() + 3));
		}
		
		if (direction ==1) {
			setX(getX() + (int)(Gdx.graphics.getDeltaTime() + 3));
		}
		
		if (direction ==2) {
			setY(getY() - (int)(Gdx.graphics.getDeltaTime() + 3));
		}
		
		if (direction ==3) {
			setX(getX() - (int)(Gdx.graphics.getDeltaTime() + 3));
		}
		//}
		}

I’ve commented a few lines out while playing with the code…I’m stumped.

Don’t know how much use this will be to you, but here’s how I’m checking if a tile is north of me, south etc


// returns false if a tile is present in the direction given.
// translated_x is your player.x
// translated_y is your player.y
	private boolean isNoTile(int direction, int translated_x, int translated_y) {
		for (Tile t : getCollision_tiles()[0]) {
			switch (direction) {
			case 0: // up
				Rectangle player1 = new Rectangle(translated_x, translated_y - tileHeight, 32, 32); // perform a move-check
				if (player1.intersects(t.getRect())) {
					return false;
				}
				break;
			case 1: // right
				Rectangle player2 = new Rectangle(translated_x + tileWidth, translated_y, 32, 32); // perform a move-check
				if (player2.intersects(t.getRect())) {
					return false;
				}
				break;
			case 2: // down
				Rectangle player3 = new Rectangle(translated_x, translated_y + tileHeight, 32, 32); // perform a move-check
				if (player3.intersects(t.getRect())) {
					return false;
				}
				break;
			case 3: // left
				Rectangle player4 = new Rectangle(translated_x - tileWidth, translated_y, 32, 32); // perform a move-check
				if (player4.intersects(t.getRect())) {
					return false;
				}
				break;
			default: // 0_0
				break;
			}
		}
		return true;
	}

Thanks. I got it working. How can I actually keep my pacman fully in a tile? i’m finding the collision detection is going 2 over so it’s not allowing it to move. I’ve tried everything I can think of lol.


public void move(Map map) {
		
		
		if (direction == 0) {
			if (isNoTile(map,direction,getX(),getY())) {
			
			
		 
				setY(getY() + (int)(Gdx.graphics.getDeltaTime() + 2));
			}
			}
			
		
		
		if (direction ==1) {
			if (isNoTile(map,direction,getX(),getY())) {
			setX(getX() + (int)(Gdx.graphics.getDeltaTime() + 2));
		}
		}
		
		if (direction ==2) {
			if (isNoTile(map,direction,getX(),getY())) {
			setY(getY() - (int)(Gdx.graphics.getDeltaTime() + 2));
		}
		}
		
		if (direction ==3) {
			if (isNoTile(map,direction,getX(),getY())) {
			setX(getX() - (int)(Gdx.graphics.getDeltaTime() + 2));
		}
		}
		
		}
	
	private boolean isNoTile(Map map, int dir, int translated_x, int translated_y) {
		System.out.println("X: " + translated_x + " Y: " + translated_y);
		for (Rectangle r : map.getBlockedTiles()) {
			switch (dir) {
			case 0:
				Rectangle up = new Rectangle(translated_x,translated_y , 16, 16);
				if (up.overlaps(r)) {
					
				return false;
				
				}
				break;
				
			case 1:
				Rectangle right = new Rectangle(translated_x+16,translated_y, 16, 16);
				if (right.overlaps(r)) {
				return false;
				}
				break;
				
			case 2:
				Rectangle down = new Rectangle(translated_x,translated_y - 16, 16, 16);
				if (down.overlaps(r)) {
				return false;
				}
				break;
				
			case 3:
				Rectangle left = new Rectangle(translated_x-16,translated_y, 16, 16);
				if (left.overlaps(r)) {
				return false;
				}
				break;
				
				default:
					break;
			}
		}
	return true;
	}
	

You would start by initializing your players position to a tiles position (Exact same coordinates as a tile).


int velocity_x = tile.width;
int velocity_y = tile.height;
if (right) {
     /* Where velocity_x is = the tiles width */
     player.x += velocity_x;
}
if (up) {
     /* Where velocity_y is = the tiles height */
     player.y += velocity_y;
}

That’s how I went from moving 2 pixels at a time to moving 1 tile at a time (Collision is way easier…!)

Thanks. I actually just figured it out. I was checking a whole tile in front of the player instead of the speed/velocity in front of the player.

Great xD glad I could help :>