0

なんらかの理由で、スプライトが左側のエッジに当たったときに跳ね返りません。プログラムは完全に機能していましたが、実際にはまったく影響を与えないはずのものを変更したところ、機能しなくなりました。

//Sprite class

public class Sprite {
private String sprite = "sprite-adult.fw.png";

private int speed;
private int dx;
private int dy;
private int x;
private int y;
private Image image;

public Sprite() {
    ImageIcon ii = new ImageIcon(getClass().getResource(sprite));
    image = ii.getImage();

            speed=6;
            dx=speed;
            dy=speed;

    x = 40;
    y = 60;
}
public void move() {
    toggleRebound();

    x += dx;
    y += dy;
}
public void toggleRebound() {
    if(x == 1366) 
        dx = negate(dx);

    if(y == 768) 
        dy = negate(dy);

    if(x == 0) 
        dx = negate(dx);

    if(y == 0) 
        dy = negate(dy);    
}
public int negate(int x) {
    return x*-1;
}
public int getX() {
    return x;
}
public int getY() {
    return y;
}
public Image getImage() {
    return image;
}
}


//SType class

public class SType extends JFrame{
public SType() {
    add(new Board());

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(1366,768);
    setLocationRelativeTo(null);
    setTitle("S - Type");
    setVisible(true);
    setResizable(false);
}
public static void main(String[] args) {
    new SType();
}
}

//Board class

public class Board extends JPanel implements ActionListener{
private Sprite sprite;
private Timer timer;

public Board() {
    setFocusable(true);
    setBackground(new Color(39,124,36));
    setDoubleBuffered(true);

    sprite = new Sprite();

    timer = new Timer(5,this);
    timer.start();
}
public void paint(Graphics g) {
    super.paint(g);

    Random rand = new Random(5398);
    for(int x=0;x<1000;x++) {
        g.setColor(new Color(22,98,19));
        g.drawOval(rand.nextInt(1368), rand.nextInt(768), 1, 20);
    }

    Graphics2D g2d = (Graphics2D)g;
    g2d.drawImage(sprite.getImage(),sprite.getX(),sprite.getY(),this);

    Toolkit.getDefaultToolkit().sync();
}
public void actionPerformed(ActionEvent arg0) {
    sprite.move();
    repaint();
}
}
4

2 に答える 2

2

最初の回答者は正しいです。これは何にも影響しません。この例ではあまり関係ありませんが、宣言ではなくコンストラクターでプライベート インスタンス変数を初期化することをお勧めします。

private int speed;
private int dx;
private int dy;

public Sprite()
{
    speed=6;
    dx=speed;
    dy=speed;
}
于 2013-07-11T20:30:23.153 に答える
1

ここで学ぶべき2つの教訓があります

まず、あなたが抱えている本当の問題は、ゼロ (またはハードコードされた左/上のサイズ) との正確な等価性によってリバウンドをチェックしていることです。これは、一度に複数のピクセルを移動すると (上記のコードのように)、境界線を見逃して通過する可能性があることを意味します。

一般的に言えば、特に一度に複数を「移動」する可能性がある場合は、より少ない数で制限をチェックすることをお勧めします。

たとえば、配列クラスを作成したい場合は、境界チェックを で行いません((idx == 0) or (idx == length))。代わりにをチェックし((idx <= 0) or (idx >= length))ます。

スプライトの位置も同じです。

第二に、特に期待が裏切られた場合に、仮定を確認することは常に役に立ちます。この場合、非常に単純な 1 つの変更がプログラムを壊したことは確かです。

しかし、それは真実ではありませんでした。それは真実ではなかったはずです。いかなる状況においても、これは次のとおりです。

private int dx = 6;
private int dy = 6;

これとは異なります:

private int speed = 6
private int dx = speed;
private int dy = speed;

したがって、2 つの測定ポイント (動作中、非動作中) の間で何かが変化しました。この追加の変更が何らかの形であなたから隠されている可能性は十分にあります - おそらくコンパイルエラーによって、あるいはプログラムの他の側面を見ているだけで、それをバウンスさせなかったのかもしれません. しかし、理由が何であれ、他の何かが変わりました。

この特定のケースでは、開始点または速度の値も変更した可能性があります。

しかし、原因が何であれ、不可能な点に到達したときは、戻って想定を再確認する必要があります。

しかし、とにかく、それが問題です。スプライトの「動き」が速すぎて、現在のリバウンドをキャッチできません。以下のテストに変更することをお勧めします。

あなたは間違っています。その変更を行っただけでは、報告された動作に変化はありませんでした。

ほとんどの場合、実際には複数の変更を行いましたが、この時点でリバウンド動作をテストしただけです。

于 2013-07-11T20:25:45.633 に答える