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 = 1 ではなく y = 0 が得られます。助けてくれてありがとう。

4

2 に答える 2

2

Java の最も基本的な契約である.equals() / .hashCode()契約に従わない。

class で両方をオーバーライドする必要がありますPoint。SO やネット上には、一般的に多くの例があります。

これがここで適用される理由は、blocksマップにPointインスタンス化した が含まれているかどうかを確認するためです。ただし、使用する a のキーは、andHashMapに大きく依存しています。そのようなマップのキーが 1 つある場合にのみ、..equals().hashCode().contains(x)kk.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たメソッドを使用しており、そのメソッドは、2 つのオブジェクトが同じオブジェクトである場合にのみ「等しい」ことを示しています。equalsObject

したがって、(たとえば) ポイント インスタンスを as として作成しnew Point(1,1)、それをキーとして使用してエントリをハッシュ テーブルに追加するとします。次に、 でポイントのルックアップを実行する場合は(1,1)、2 番目のポイント インスタンスを ( で new Point(1,1)) 作成し、 を呼び出しますget(...)。しかし、この新しいポイントはのポイント オブジェクトp1.equals(p2)です (「false」です!)... そのため、ルックアップは失敗します。

解決策は、2 つのオブジェクトが同じ属性と属性を持つ場合に「等しい」ようequalsに、Pointクラスでオーバーライドすることです。/コントラクトが満たされるようオーバーライドする必要があります。Pointxyhashcodeequals()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 に答える