Я создаю боевой корабль, где каждый раунд игрок может выбрать 4 маршрута корабля, выбрав для него 4 самых близких плитки с помощью мыши.
Теперь в следующем gif, вы можете увидеть, буду ли я нависнуть на самом краю плитки, он выберет сразу две плитки или даже 4 сразу, если вы держите мышью в середине 4-х плиток:
gif http://gyazo.com/4d9f4a07b19d01642f92d3818f36b5fa.gif
Это не должно происходить в игре, как я могу это предотвратить?
Это код обновления:
/**
*
* @param x mouse X
* @param y mouse Y
*/
public void checkHover(int x, int y) {
for (int i = 0; i < tiles[0].length; i++) {
for (int j = 0; j < tiles[1].length; j++) {
// get coordinates from tile
int x1 = i * (sprite.getWidth() - 1);
int y1 = j * (sprite.getHeight() - 1);
// If we have screen translate, we can cancel it for
// this situation
int realX = x - this.translate.getX();
int realY = y - this.translate.getY();
// checking if mouse inside tile
if (realX >= x1 && realX <= x1 + sprite.getWidth() &&
realY >= y1 && realY <= y1 + sprite.getHeight()) {
// set tile to hovered sprite
this.tiles[i][j].setHover(true);
}
else {
// cancel hovered sprite
this.tiles[i][j].setHover(false);
}
}
}
}
Как я могу это предотвратить?
Вместо двух циклов я бы вычислил индекс массива 2d, основанный на позиции x и y мыши, разделив положение x и y на сколько места от одной плитки до следующей (которая выглядит как ширина плитки плюс 1, пустая рамка). Это приведет к тому, что границы будут поддерживать определенную сторону, но похоже, что вы не хотите выбирать две плитки в любом случае.
Когда у вас есть индекс плитки, lastHighlightedTile
подсветку и сохраните ссылку на нее с переменной экземпляра, как lastHighlightedTile
, но прежде чем вы это сделаете, также вызовите lastHighlightedTile.setHover(false);
,
Если индекс плитки недействителен, как если бы мышь вышла из области плитки, не обращайтесь к массиву и все еще вызывайте lastHighlightedTile.setHover(false);
,
Это должно исправить выделение нескольких фрагментов, а также позволит отключить предыдущую подсветку (решение выхода из текущего цикла может не отключить предыдущую подсветку).
EDIT: другое решение: просто объявите логическое начало в начале метода и установите только в том случае, если этот логический объект все еще является ложным. После того, как вы установили плитку, также установите для boolean значение true, что предотвратит установку других.
public void checkHover(int x, int y) {
boolean hasTurnedOneOn = false;
for (int i = 0; i < tiles[0].length; i++) {
for (int j = 0; j < tiles[1].length; j++) {
// get coordinates from tile
int x1 = i * (sprite.getWidth() - 1);
int y1 = j * (sprite.getHeight() - 1);
// If we have screen translate, we can cancel it for
// this situation
int realX = x - this.translate.getX();
int realY = y - this.translate.getY();
// checking if mouse inside tile
if (realX >= x1 && realX <= x1 + sprite.getWidth() &&
realY >= y1 && realY <= y1 + sprite.getHeight() && !hasTurnedOneOn) {
// set tile to hovered sprite
this.tiles[i][j].setHover(true);
hasTurnedOneOn = true;
}
else {
// cancel hovered sprite
this.tiles[i][j].setHover(false);
}
}
}
}
Предполагая, что ширина спрайта равна 50, я вижу, что первый заголовок имеет координату x1-x2 (0-50), второе название имеет (49-100), третье имеет (99-150)... То же самое для y-измерения.
Поэтому, когда указатель находится в точке (x) = (50), он отображает (x1 - x2) (0-50) и (49 -1 00) заголовки.
Почему вы вычитаете 1 из ширины/высоты sprite? попробуйте с этим:
// get coordinates from tile
int x1 = i * (sprite.getWidth());
int y1 = j * (sprite.getHeight());
Редактировать: я написал пример приложения, которое запустило мое решение:
public class App {
Tile[][] tiles;
Sprite sprite;
public static void main(String[] args) {
App app = new App();
app.init();
app.checkHover(50, 50);
app.printHovers();
}
private void init() {
sprite = new Sprite();
tiles = new Tile[10][10];
for (int i = 0; i < tiles[0].length; i++) {
for (int j = 0; j < tiles[1].length; j++) {
tiles[i][j] = new Tile();
}
}
}
public void checkHover(int x, int y) {
for (int i = 0; i < tiles[0].length; i++) {
for (int j = 0; j < tiles[i].length; j++) {
// get coordinates from tile
int x1 = i * (sprite.getWidth());
int y1 = j * (sprite.getHeight());
// If we have screen translate, we can cancel it for
// this situation
// int realX = x - this.translate.getX();
// int realY = y - this.translate.getY();
int realX = x;
int realY = y;
// checking if mouse inside tile
if (realX >= x1 && realX < x1 + sprite.getWidth()
&& realY >= y1 && realY < y1 + sprite.getHeight()) {
// set tile to hovered sprite
this.tiles[i][j].setHover(true);
} else {
// cancel hovered sprite
this.tiles[i][j].setHover(false);
}
}
}
}
public void printHovers() {
for (int i = 0; i < tiles[0].length; i++) {
for (int j = 0; j < tiles[i].length; j++) {
System.out.print((tiles[i][j].isHover() ? "Y" : "O") + " ");
}
System.out.println();
}
}
public class Sprite {
public int getWidth() {
return 50;
}
public int getHeight() {
return 50;
}
}
public class Tile {
private boolean hover;
public boolean isHover() {
return hover;
}
public void setHover(boolean hover) {
this.hover = hover;
}
}
}
Он отлично работает для (49, 49), (49, 50), (50, 49) и (50, 50) коордов. Итак, сначала вы должны удалить вычеты -1 и изменить <=
test на <
.