1

私は今取り組んでいるパックマンの動きで小さな問題に直面しました。

元のパックマンの動きに似た動きをする方法を見つけることができないようです. どのように動かしたいかを説明するために、この写真をアップロードしました。

ここに画像の説明を入力

現状では、黄色の長方形と青い壁の間で衝突が機能しています。問題は、写真のように左に移動して上矢印をクリックすると、停止せずに移動を続け、空きスペースがあるときに上に移動することです。

現在、次のように上矢印をクリックすると、黄色の四角形が停止します。

ここに画像の説明を入力

動きを含む pacman クラスと、衝突が検出されたときのボード クラスのコードをアップロードしました。

パックマンクラス

public class Pacman {

private String pacmanup = "pacmanup.png";
private String pacmandown = "pacmandown.png";
private String pacmanleft = "pacmanleft.png";
private String pacmanright = "pacmanright.png";

private int dx;
private int dy;
private int x;
private int y;
private int width;
private int height;
private boolean visible;

private Image imageup;
private Image imagedown;
private Image imageleft;
private Image imageright;

public Pacman() {

    Thread thread = new Thread();

    thread.start();

    ImageIcon i1 = new ImageIcon(this.getClass().getResource(pacmanup));
    imageup = i1.getImage();

    ImageIcon i2 = new ImageIcon(this.getClass().getResource(pacmandown));
    imagedown = i2.getImage();

    ImageIcon i3 = new ImageIcon(this.getClass().getResource(pacmanleft));
    imageleft = i3.getImage();

    ImageIcon i4 = new ImageIcon(this.getClass().getResource(pacmanright));
    imageright = i4.getImage();

    width = imageup.getWidth(null);
    height = imageup.getHeight(null);
    visible = true;
    x = 27;
    y = 27;

}

public int getDx() {
    return dx;
}

public void setDx(int dx) {
    this.dx = dx;
}

public int getDy() {
    return dy;
}

public void setDy(int dy) {
    this.dy = dy;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}

public void setX(int x) {
    this.x = x;
}

public void setY(int y) {
    this.y = y;
}

public Image getImageup() {
    return imageup;
}

public Image getImagedown() {
    return imagedown;
}

public Image getImageleft() {
    return imageleft;
}

public Image getImageright() {
    return imageright;
}

public void setVisible(boolean visible) {
    this.visible = visible;
}

public boolean isVisible() {
    return visible;
}

public Rectangle getBounds() {
    return new Rectangle(x, y, width, height);
}

public Rectangle getOffsetBounds() {
    return new Rectangle(x + dx, y + dy, width, height);
}

public void move() {

    x += dx;
    y += dy;
}

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) {
        dx = -1;
        dy = 0;
    }

    if (key == KeyEvent.VK_RIGHT) {
        dx = 1;
        dy = 0;
    }

    if (key == KeyEvent.VK_UP) {
        dx = 0;
        dy = -1;
    }

    if (key == KeyEvent.VK_DOWN) {
        dx = 0;
        dy = 1; 
    }
}

public void keyReleased(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) {

    }

    if (key == KeyEvent.VK_RIGHT) {

    }

    if (key == KeyEvent.VK_UP) {

    }

    if (key == KeyEvent.VK_DOWN) {

    }


}

Board クラスのコード

Rectangle r5 = pacman.getOffsetBounds();

    for (int j = 0; j<barriers.size(); j++) {
        Barrier b = (Barrier) barriers.get(j);
        Rectangle r4 = b.getBounds();

        if (r5.intersects(r4)) {

            pacman.setDx(0);
            pacman.setDy(0);
            break;

        }

    }

    pacman.move();

}

黄色の長方形が移動している方向を検出する、ボード クラス内で direction と呼ばれる文字列を作成しました。

「左」「上」「右」または「下」

すでにいくつかのコードを書き込もうとしましたが、機能していません。これが私が試したものです:

      // moving to the left and tried go up
            else if (pacman.getDx() == 0 && pacman.getDy() == -1 && direction.equals("left")) {
                pacman.setDy(0);
                pacman.setDx(-1);
                break;

さて、左に移動して上をクリックすると、左に移動し続けますが、本来あるべきように空きスペースに移動しません:)

キーアダプター/押されたキーで何かですか?押し上げたキーがアクティブになっていないか、クリックしたときに何かが発生している可能性がありますか?

4

1 に答える 1

0

私の見方では、ここには2つの問題があります。

(課題1)

pacman を動かし続けたい場合は、dx or dy別のキーが押されるまで値を変更し続けます。とにかく、それが古典的なパックマンがどのように機能したかです。それは常に動き続けた/最後の の方向に動き続けようとしたkeypressed. (実際のゲーム メカニクスはこちらでご覧ください - https://www.google.com/doodles/30th-anniversary-of-pac-man )

(課題 2)

古典的な pacman を実装しようとしていない場合 (あなたがやろうとしていることからすると、古典的な pacman を実装しているようには見えません)、およびコントロールの動作方法を少し変更したい場合は、インテリジェントに切り替えるようにします。キー押下の履歴に基づいて方向を決定するには、キー押下を保存することを検討してください。問題は、追跡したいキー押下方向の数です。

2 つのキー押下のみを追跡すると仮定すると、常に 2 つのペアarrayのみを格納するサイズ 2 の が必要になります。キーkey:value方向であり、は、そうでない方向 (すなわち または ) に移動できるかどうかです。boolean truefalse

これを使用しarrayて問題を解決する方法は次のとおりです。

方向キーが押されたら にセットしarray[0].key、その方向に移動できるかどうかを確認します。可能であれば、 to の値を設定し、array[0].valueこの値を使用して、別の関数のor変数trueの値を変更する必要があるかどうかを確認します。and の状態をチェックして、その方向に移動できるかどうかを判断します。実際の機能の詳細については後述します。すでに基本的なメソッドが実装されているので、それで問題ありません。いくつかの条件を追加して、少し変更するだけです。dxdyarray[0].keyarray[0].valuemovemove

次に、2 番目のキー ( などup key) が押されたら、次の操作を行います。

  1. 設定temp = array[0]
  2. 設定array[0].key = 'up'
  3. set array[1].value= の方向に移動できるかどうかを確認し、移動できるarray[0].key場合は true を設定し、移動できない場合は false を設定します。
  4. または_ array[1] = temp_ array[1].value_truefalse

array[1]最も古いキーを押したアクションを に移動し、最後にキーを押したアクションを に移動したことに注意してくださいarray[0]

array[0]この時点で、最後に押されたキーの方向値が保存されているため、常に最初の方向に移動しようとする規則を設定し、次に移動しようとしますarray[1]

ブール値をおよびに設定してarray[0]およびの方向に移動できるかどうかを確認した後、どこに移動できるかがわかり、実際に移動する準備が整いました。array[1]array[0].valuearray[1].value

したがって、 move メソッドで次の操作をif(array[0].value==true)行います。

  1. の方向に移動してarray[0]無視array[1]します (つまり、ループを使用して移動ロジックを実装する場合はブレークします)。

else if(array[1].value == true):

  1. の方向に移動します。array[1]

    関数が戻り、新しい (x,y) になったらmove()、ステップ 1 に戻り、最初からやり直します。

実装する必要がある手順が明確であることを願っています。

于 2015-02-01T02:24:31.477 に答える