0

我对编程有点陌生,想尝试制作一个比我以前的游戏更难的盒子式 2d 游戏来学习。唉,我还是新手,所以如果可能的话,请降低你的答案

几个小时以来,我一直在玩弄哈希图,但似乎无法弄清楚为什么将我的密钥提供给 java 不会给我它的价值。

package main;

public class Point {

  private int x;
  private int y;

  public Point(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int getX() {
    return this.x;
  }
  public int getY() {
    return this.y;
  }
}


public Map<Point, Integer> Blocks = new HashMap<Point, Integer>();

int x = 0;
int y = 0;

while (active == true) {

  Point Apple = new Point(x, y);
  Blocks.put(Apple, 1);

  if (x <= 800) {
    x += 32;
  } else {
    x = 0;
    y += 32;
  }

  if (y > 600) {
    active = false;
  }
}

MouseX = (Mouse.getX() / 32) * 32;
MouseY = (Mouse.getY() / 32) * 32;
Point rawr = new Point(MouseX, MouseY);

if (Blocks.containsKey(rawr)) {
  y = Blocks.get(rawr);
}

结果,我得到 y = 0 而不是 y = 1。感谢您提供的任何帮助。

4

2 回答 2

2

你没有遵守 java 最基本的契约:.equals() / .hashCode()契约。

您需要在 class 中覆盖它们Point。这里有很多关于 SO 和一般网络的例子。

现在,为什么这适用于这里是因为您尝试查看blocks地图是否包含Point您已实例化的 a 。但是您使用的 a 中的键在HashMap很大程度上依赖于.equals()and .hashCode()。它.contains(x)当且仅当映射的一个键k使得k.equals(x).

对于您的班级:

@Override
public int hashCode()
{
    return 31 * x + y;
    // If using Java 7, this can be:
    // returns Objects.hash(x, y);
}

@Override
public boolean equals(final Object o)
{
    // No object instance is equal to null
    if (o == null)
        return false;
    // If the object is the same, this is true
    if (this == o)
        return true;
    // If not the same object class, false
    if (getClass() != o.getClass())
        return false;

    final Point other = (Point) o; // safe to cast since getClass() == o.getClass()
    return x == other.x && y == other.y; // test instance member equality
}
于 2013-06-10T00:34:52.767 回答
0

根本问题是您的Point密钥对其equals方法的语义错误。您正在使用equals从 from 继承的方法Object,并且方法表示两个对象是“相等的”,当且仅当它们是同一个对象时。

因此,假设您创建(例如)一个点实例new Point(1,1)并将其用作向哈希表添加条目的键。然后,当您想要查找 处的点时(1,1),您创建第二个点实例(使用 new Point(1,1))...并调用get(...). 但是这个新点是一个不同的点对象(p1.equals(p2)是'假'!)......所以查找失败。

equals解决方案是在您的类中覆盖,Point以便两个Point对象“相等”,如果它们具有相同的xy属性。然后您需要覆盖hashcode以便满足equals()/hashcode()合同。

这是一个例子:

//
// The fields are 'final' because we want make it clear that a Point
// is immutable.  The class itself is 'final' to simplify the problem of
// testing for equality.  (Equality between an instance of a class and 
// an instance of a subclass can be problematic. If the subclass overrides
// the `equals` method you get in problems with the requirement that equality
// is symmetric; i.e. ensuring that 't.equals(st) == st.equals(t)'.  Making 
// Pint `final` removes that potential issue.)
//
public final class Point {

  private final int x;
  private final int y;

  public Point(int x, int y) { this.x = x; this.y = y; }

  public int getX() { return this.x; }
  public int getY() { return this.y; }

  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (!(other instanceof Point)) {
      return false;
    }
    Point point = (Point) other;
    return this.x = point.x && this.y == point.y;
  }

  public int hashcode() {
    return this.x + 31 * this.y;
  }
}
于 2013-06-10T01:07:25.193 回答