Coordinate[] coords = {
new Coordinate(3093, 3630), new Coordinate(3095, 3632), new Coordinate(3098, 3633),
new Coordinate(3101, 3633), new Coordinate(3104, 3631), new Coordinate(3106, 3629),
new Coordinate(3107, 3627), new Coordinate(3108, 3624), new Coordinate(3109, 3620),
new Coordinate(3108, 3617), new Coordinate(3106, 3614), new Coordinate(3102, 3613),
new Coordinate(3099, 3613), new Coordinate(3097, 3613), new Coordinate(3093, 3614),
new Coordinate(3090, 3617), new Coordinate(3087, 3619)
};
int random = Misc.random(coords.length - 1);
Coordinate coord = coords[random];
boolean found = false;
if (insidePlayers.size() < coords.length) {
if (spawnPoints.contains(coord)) {
found = false;
}
while (!found) {
random = Misc.random(coords.length - 1);
coord = coords[random];
if (!spawnPoints.contains(coord)) {
player.spawnPointX = coords[random].getX();
player.spawnPointY = coords[random].getY();
spawnPoints.add(coord);
found = true;
break;
}
}
}
else {
player.spawnPointX = coords[random].getX();
player.spawnPointX = coords[random].getY();
}
基本上我在这里要做的是,如果有比可用坐标(点数)更多的客户端,那么给每个玩家自己的坐标(所以其他客户端不能有相同的坐标)。
但遗憾的是,它不起作用,有时客户端会得到相同的坐标。 为什么会这样?我做错了什么?
协调班级:
public class Coordinate {
private int x = 0;
private int y = 0;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
的ArrayList:
public static ArrayList<Coordinate> spawnPoints = new ArrayList<Coordinate>();
那有什么不对?
答案 0 :(得分:1)
您需要覆盖Coordinate类中的equals()
。
@override
public void equals(Object o){
if(o==null)
return false;
if(!(o instanceof Coordinate)){
return false;
Coordinate newO = (Coordinate) o;
if(this.x == newO.x && this.y == newO.y)
return true
return false;
}
这是因为ArrayList#contains使用的ArrayList#indexOf()定义为:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i])) /// <--- Uses .equals()
return i;
}
return -1;
}
注意:当你在它时也会覆盖hashCode()。在你的情况下你并不真的需要它,但它是一个很好的做法,如果你使用基于散列的数据结构将帮助你。 This会有所帮助。
答案 1 :(得分:1)
所以基本上你有一组生成点,并且你想在这些点上产生玩家,但没有两个玩家可以拥有相同的生成点。一种更简单的方法是在将一个坐标提供给一个玩家后从该列表中删除一个坐标。不确定你是如何在客户(玩家)中提供的,如果这个解决方案没有用,请详细说明。
Coordinate[] coords = {
new Coordinate(3093, 3630), new Coordinate(3095, 3632), new Coordinate(3098, 3633),
new Coordinate(3101, 3633), new Coordinate(3104, 3631), new Coordinate(3106, 3629),
new Coordinate(3107, 3627), new Coordinate(3108, 3624), new Coordinate(3109, 3620),
new Coordinate(3108, 3617), new Coordinate(3106, 3614), new Coordinate(3102, 3613),
new Coordinate(3099, 3613), new Coordinate(3097, 3613), new Coordinate(3093, 3614),
new Coordinate(3090, 3617), new Coordinate(3087, 3619)
};
public static List<Coordinate> coordinates = new ArrayList<>(Arrays.asList(coords));
public static final Random rnd = new java.util.Random();
if(!coordinates.isEmpty())
int randomIndex = rnd.nextInt(coordinates.size());
Coord randomCoord = coordinates.get(randomIndex);
player.spawnPointX = randomCoord.getX();
player.spawnPointY = randomCoord.getY();
coordinates.remove(randomIndex);
else
System.out.println("No more coordinates left to assign to player");
答案 2 :(得分:0)
我认为问题是两个因素的结合:1)每次在方法中分配一个新的coords
数组; 2)您的Coordinate
课程未实施equals()
和hashCode()
。这些导致问题的原因是从equals()
继承的hashCode()
和Object
的默认实现基于对象标识,而不是值的相等性。结果是,如果在一次调用中,Coordinate
的值(例如)x = 3093且y = 3630已添加到spawnPoints
,则在下一次调用时,新的Coordinate
具有相同x和y值的对象将测试为未包含在spawnPoints
中。
我认为可以通过以下两种方式之一解决这个问题:
coords
数组声明为static final
字段,而不是每次都在方法中分配新数组。那么对象身份就足以满足你的逻辑。Coordinate.equals(Object)
和Coordinate.hashCode()
,以便具有相同Coordinate
和x
字段值的y
个对象测试相同并具有相同的哈希码。< / LI>
醇>
即使第一种方法解决了问题,您也应该强烈考虑实施equals
和hashCode
,特别是如果要将Coordinate
个对象添加到其他集合中。