-3
public class Main {

    public static void main(String[] args) {
        GUI gui = new GUI();
        GameHandler gameHandler = new GameHandler();
        while (!gui.shouldStop()) {
            while (gui.isRunning()) {
                gameHandler.run();
            }
        }
    }

}


import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class GUI extends JFrame implements KeyListener, WindowListener {

    private JLabel label;
    private boolean run = false;
    private boolean stop = false;

    public GUI() {
        label = new JLabel("Not running.");
        JPanel panel = new JPanel();
        panel.setSize(300, 200);
        panel.add(label);
        setSize(300, 200);
        add(panel);
        addKeyListener(this);
        addWindowListener(this);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public boolean isRunning() {
        return run;
    }

    public boolean shouldStop() {
        return stop;
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            String text = label.getText().equalsIgnoreCase("Not running.") ? "Running!" : "Not running.";
            label.setText(text);
            run = !run;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        stop = true;
    }

    @Override
    public void windowClosed(WindowEvent e) {
        stop = true;
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }
}


import java.awt.*;

public class GameHandler {

    private Elektra elektra;
    private Button popupExitButton;

    public GameHandler() {
        elektra = new Elektra();
        popupExitButton = new Button(Button.EXIT_POPUP_IMAGE_PATH);
    }

    public void run() {
        if (elektra.isAlive()) {
            try {
                new Robot().mouseMove(20, 90);
            } catch (AWTException e) {
                e.printStackTrace();
            }
        } else if (popupExitButton.isVisible()) {
            try {
                new Robot().mouseMove(90, 90);
            } catch (AWTException e) {
                e.printStackTrace();
            }
        }
    }

}

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Button {

    BufferedImage image;

    public Button(String fileName) {
        try {
            image = ImageIO.read(ClassLoader.getSystemResourceAsStream(fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isVisible() {
        try {
            return new ImageSearcher(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))).containsSubImage(image);
        } catch (AWTException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static final String EXIT_POPUP_IMAGE_PATH = "images/exitPopupButton.png";

}

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Elektra {

    String imagePath = "images/elektra.png";
    BufferedImage image;

    public Elektra() {
        try {
            image = ImageIO.read(ClassLoader.getSystemResourceAsStream(imagePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isAlive() {
        try {
            return new ImageSearcher(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))).containsSubImage(image);
        } catch (AWTException e) {
            e.printStackTrace();
        }
        return false;
    }

}

私のプログラムは、特定の画像の画面をチェックすることになっています。それが見つかった場合は、マウスを動かす必要があります。問題は、メッセージをログに記録しない限り、機能しないことです。何故かはわからない。

System.out.println( "blah");を追加した場合 メインクラスの各whileループで、動作します。しかし、私がそれらを含めなければ、それは含まれません。誰かがこれを説明できますか...?なぜこれが起こるのか私には意味がありません。これは、デバッガーを使用している場合にも発生します。デバッグ中は機能しますが、実行中は機能しません。

動作する場合の例:

public class Main {

    public static void main(String[] args) {
        GUI gui = new GUI();
        GameHandler gameHandler = new GameHandler();
        while (!gui.shouldStop()) {
            System.out.println("..");
            while (gui.isRunning()) {
                System.out.println("..");
                gameHandler.run();
            }
        }
    }

}
4

3 に答える 3

2

このMSCCEは期待どおりに動作しますか? (私はそれが何をすべきかについて完全に明確ではないことを認めなければなりません.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

class Main {

    public static void main(String[] args) {
        GameHandler gameHandler = new GameHandler();
        GUI gui = new GUI(gameHandler);
        gameHandler.run();
    }
}

class GUI extends JFrame implements KeyListener {

    private JLabel label;
    private boolean run = false;
    private boolean stop = false;
    GameHandler gameHandler;

    public GUI(GameHandler gameHandler) {
        this.gameHandler = gameHandler;
        label = new JLabel("Not running.");
        JPanel panel = new JPanel();
        panel.setSize(300, 200);
        panel.add(label);
        setSize(300, 200);
        add(panel);
        addKeyListener(this);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public boolean isRunning() {
        return run;
    }

    public boolean shouldStop() {
        return stop;
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            String text = label.getText().equalsIgnoreCase("Not running.") ? "Running!" : "Not running.";
            label.setText(text);
            run = !run;
            if (run) {
                gameHandler.run();
            } else {
                gameHandler.stop();
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
}

class GameHandler {

    private Elektra elektra;
    private Button popupExitButton;
    Timer timer;

    public GameHandler() {
        elektra = new Elektra();
        popupExitButton = new Button("Button.EXIT_POPUP_IMAGE_PATH");
        timer = new Timer(400, listener);
    }

    public void run() {
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

    ActionListener listener = new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            System.out.println("elektra.isAlive(): " + elektra.isAlive());
            if (elektra.isAlive()) {
                try {
                    new Robot().mouseMove(20, 90);
                } catch (AWTException e) {
                    e.printStackTrace();
                }
            } else if (popupExitButton.isVisible()) {
                try {
                    new Robot().mouseMove(90, 90);
                } catch (AWTException e) {
                    e.printStackTrace();
                }
            }
        }
    };

}

class Button {

    BufferedImage image;

    public Button(String fileName) {
        try {
            //image = ImageIO.read(ClassLoader.getSystemResourceAsStream(fileName));
            image = new Robot().createScreenCapture(new Rectangle(0,0,200,200));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isVisible() {
        try {
            return new ImageSearcher(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))).containsSubImage(image);
        } catch (AWTException e) {
            e.printStackTrace();
        }
        return false;
    }

}

class Elektra {

    BufferedImage image;

    public Elektra() {
        try {
            image = new Robot().createScreenCapture(new Rectangle(0,0,200,50));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isAlive() {
        try {
            return new ImageSearcher(
                new Robot().createScreenCapture(
                    new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())))
                    .containsSubImage(image);
        } catch (AWTException e) {
            e.printStackTrace();
        }
        return false;
    }

}

class ImageSearcher {

    BufferedImage mainImage;

    public ImageSearcher(BufferedImage image) {
        mainImage = image;
    }

    public boolean containsSubImage(BufferedImage subImage) {
        int mainWidth = mainImage.getWidth();
        int mainHeight = mainImage.getHeight();
        int width = subImage.getWidth();
        int height = subImage.getHeight();
        for (int xOffset = 0; xOffset < mainWidth && xOffset + width < mainWidth; xOffset++) {
            for (int yOffset = 0; yOffset < mainHeight && yOffset + height < mainHeight; yOffset++) {
                if (picturesEquivalent(subImage, xOffset, yOffset)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean picturesEquivalent(BufferedImage subImage, int xOffset, int yOffset) {
        int mainWidth = mainImage.getWidth();
        int mainHeight = mainImage.getHeight();
        int width = subImage.getWidth();
        int height = subImage.getHeight();
        for (int x = 0; x < width && xOffset + x < mainWidth; x++) {
            for (int y = 0; y < height && yOffset + y < mainHeight; y++) {
                int mainRGB = mainImage.getRGB(xOffset + x, yOffset + y);
                int subRGB = subImage.getRGB(x, y);
                if (mainRGB != subRGB) {
                    return false;
                }
            }
        }
        return true;
    }
}
于 2012-05-19T01:55:19.823 に答える
1

これを具体的にバックアップするものをインターネット上で見つけるのに苦労していますが、あなたのprintステートメントはプログラムを遅くして、すべてを正しい順序で実行できるようにしていると思います. Swing リクエストは 1 つのスレッドから起動されるため、特に KeyEvents などの入力イベントが多数ある場合は、Hover が言うように、イベントが絡みやすくなります。この問題を解決するには、Thread.sleep を試すこともできますが、while ループを使用しないか、swing を使用しないようにプログラムを書き直す方がよいでしょう。

于 2012-05-19T01:27:22.637 に答える
0

アプリケーションを適切にマルチスレッド化します。

イベント ディスパッチャー スレッド(google this!)で作業することはできるだけ避けてください。UI を変更する場合にのみ使用してください。その中で待機ループを実行しないでください。プログラムがデッドロックする可能性さえあります。

アプリケーションがいつ機能し、いつ (およびどのように) 待機するかを計画することに、より多くの時間を費やしてください。アプリケーションが CPU を 100% 浪費するのは望ましくありません。

于 2012-05-19T11:40:41.650 に答える