2015-11-28 5 views
3

Я застрял в обнаружении столкновений и о том, как обращаться с ним в течение ОЧЕНЬ долгого времени. Мне нужна помощь, чтобы понять, как использовать обнаружение столкновений с помощью редактора карт Tiled. У меня есть файл TMX, который разобран и отображается с движением плеера, камеры и клавиатуры. Я не знаю, как это сделать, чтобы столкнуться. Моя карта имеет 2 слоя, один для травы и плитки, на которых вы можете ходить, а другой - objectLayer. Я видел, как люди говорили, что я должен перебирать все плитки в слое объектов и назначать им прямоугольники. У меня нет идеи, как это сделать, и я ищу кое-какие идеи.Обнаружение столкновений с Java, Slick2D и редактором карт из плитки

Мой главный вопрос: как мне пройти через мой слой и получить все плитки и назначить им прямоугольники.

игры Класс:

public class Game extends BasicGameState { 

Player player; 
Camera cam; 
Map map = new Map(); 

public void init(GameContainer container, StateBasedGame sbg) throws SlickException { 
    map.init(); 
    cam = new Camera(0, 0); 
    player = new Player(new Image("res/textures/player.png"), container.getWidth()/2, container.getHeight()/2, 32, 32); 
} 

public void update(GameContainer container, StateBasedGame sbg, int delta) throws SlickException { 
    cam.tick(player); 
    player.update(container, delta, map); 
} 

public void render(GameContainer container, StateBasedGame sbg, Graphics g) throws SlickException { 
    g.translate(-cam.getX(), -cam.getY()); 
     map.render(); 
     player.render(g); 
    g.translate(cam.getX(), cam.getY()); 
} 

public int getID() { 
    return 1; 
} 

}

игрока Класс:

public class Player { 

float x, y; 

int width, height; 
double velX = 0.4; 
double velY = 0.4; 

Image img; 

public Player(Image img, float x, float y, int width, int height) { 
    this.img = img; 
    this.x = x; 
    this.y = y; 
    this.width = width; 
    this.height = height; 
} 

public void init() throws SlickException { 

} 

public void update(GameContainer container, int delta, Map map) { 
    Input input = container.getInput(); 

    if (input.isKeyDown(Input.KEY_D)) x += velX; 
    if (input.isKeyDown(Input.KEY_A)) x -= velX; 
    if (input.isKeyDown(Input.KEY_W)) y -= velY; 
    if (input.isKeyDown(Input.KEY_S)) y += velY; 

} 

public void render(Graphics g) { 
    //g.scale(-2, -2); 
    g.drawImage(img, x, y); 
} 

public float getX() { 
    return x; 
} 

public float getY() { 
    return y; 
} 

}

класс Карта:

public class Map { 

TiledMap map; 

public void init() throws SlickException { 
    map = new TiledMap("res/map/zenith.tmx"); 
} 

public void render() throws SlickException { 
    map.render(0, 0); 
} 

}

ответ

2

Я не слишком хорошо разбираюсь в методах получения плитки, но это определенно в Javadoc. http://slick.ninjacave.com/javadoc/

Для проверки конфликтов с игроком вам необходимо изменить свое движение, чтобы проверить, будет ли новое местоположение игрока иметь столкновение, иначе вы застрянете на них.

public void update(GameContainer container, int delta, Map map) { 
    Input input = container.getInput(); 
    float dx = 0, dy = 0; 
    // add to dx and dy instead of moving the player straight away. 
    if (input.isKeyDown(Input.KEY_D)) dx += velX; 
    if (input.isKeyDown(Input.KEY_A)) dx -= velX; 
    if (input.isKeyDown(Input.KEY_W)) dy -= velY; 
    if (input.isKeyDown(Input.KEY_S)) dy += velY; 
    // here we check the collisions, you can fiddle with this if statement and it'll behave differently. 
    if(dx != 0 || dy != 0){ 
     if(map.checkCollision(x+dx,y+y){ 
      x+=dx; 
      y+=dy; 
     } 
    } 
} 

Что касается проверки самого столкновения вам нужен новый метод в классе карты, который создает прямоугольник для игрока и проверок в отношении массива 2D внутри класса карты, который держит ваши столкновения. Вы можете заполнить этот массив, когда карта будет проиндексирована путем прокрутки вашей карты Tiled через необходимый слой и проверки, является ли черепица столкновением с getTile (x, y). Если плитка имеет правильные свойства столкновения вы создаете прямоугольник в этом месте в 2D-массив с чем-то вроде этого:

collisionArray[x][y] = new Rectangle(x,y,TILEWIDTH,TILEHEIGHT); 

Теперь вы можете проверить столкновения внутри

map.checkCollision(x,y) 

и с прямоугольник, созданный для игрока с помощью

Rectangle player = new Rectangle(x,y,PLAYERWIDTH,PLAYERHEIGHT); 

Собирает все вместе, то вы можете проверить на пересечение с любой плиткой в ​​массиве столкновений с .intersect (г), как mentio ранее, и map.collision может вернуть true игроку, который должен остановить движение игрока.

Надеюсь, что это было не слишком запутанно, javadoc очень полезен, и Кевин Стекс писал о проверке столкновений только с 2D-массивами с различными размерами коллизионных ящиков. http://www.cokeandcode.com/main/tutorials/tile-maps/

+1

Вау, это было удивительно подробный ответ и хорошо поставил. Я собираюсь попробовать это прямо сейчас и посмотреть, работает ли это. Теперь это имеет большее значение, большое вам спасибо. – Phippre

+0

Im зацикливается на моей карте на объекте Layer, и если он получает tileid из 1, то он добавляет прямоугольник в массив, но он дает мне некоторую ошибку. \t Rectangle [] [] collisionArray; \t \t общественных недействительный Init() бросает SlickException { \t \t карты = новый TiledMapPlus ("Рез/карта/zenith.tmx"); \t \t int objectLayer = map.getLayerIndex ("objectLayer"); \t \t для (INT х = 0; х Phippre

+0

Вам может понадобиться intialise массив столкновений с пустыми прямоугольниками в петле через него. Какая ошибка? – Smallbro

1

Хорошо, теперь им получение исключения нулевого указателя в моем checkCollision()

public void assignRectangles() { 
    int objectLayer = map.getLayerIndex("objectLayer"); 
    for (int x = 0; x < map.getWidth(); x++) { 
     for (int y = 0; y < map.getHeight(); y++) { 
      if (map.getTileId(x, y, objectLayer) == 1){ 
       collisionArray[x][y] = new Rectangle(x * 32, y * 32, 32, 32); 
      } 
     } 
    } 
} 

public boolean checkCollision(float x, float y) { 
    for (int j = 0; j < collisionArray.length; j++) { 
     for (int i = 0; i < collisionArray[j].length; i++) { 
      if (collisionArray[j][i].getX() == x || collisionArray[j][i].getY() == y) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

Im получать его на линии, где это сказать, если (collisionArray [J] [я] .getX() = = х || collisionArray [J] [я] .getY() == у)

Не знаю, почему им получить его, хотя

+0

Установите каждое из значений в collisionArray на новый прямоугольник размером 0,0 на карте intialisation или проверьте, не имеет ли значение collisionArray, равное нулю. – Smallbro

+0

Я зациклился через collisionArray, и все значения там возвращают нуль. – Phippre

 Смежные вопросы

  • Нет связанных вопросов^_^