0

先週の検索では、これを行う方法を理解しようとするための実用的なヘルプが表示されませんでした. ユーザーがバックスペースを押すと、ゲームが保存されます。上部に「保存中..」という小さなボックスが表示されるように設定し、それを約2秒間そのままにしておきます。このコードでボタンが押されている間、それを表示させることができます:

if (key.save) {
    font = new Font(null, 0, 16);
    g.setFont(font);
    g.setColor(Color.DARK_GRAY);
    g.fillRect(getWidth() / 2 - 40, -1, 80, 35);
    g.setColor(Color.BLACK);
    g.drawRect(getWidth() / 2 - 40, -1, 80, 35);
    g.setColor(Color.white);
    g.drawString("Saving..", getWidth() / 2 - 30, 22);
}

ただし、このコードは機能しません。上部にボックスが表示されません。

if (key.save) {
    ActionListener action = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Font font = new Font(null, 0, 16);
            g.setFont(font);
            g.setColor(Color.DARK_GRAY);
            g.fillRect(getWidth() / 2 - 40, -1, 80, 35);
            g.setColor(Color.BLACK);
            g.drawRect(getWidth() / 2 - 40, -1, 80, 35);
            g.setColor(Color.white);
            g.drawString("Saving..", getWidth() / 2 - 30, 22);
        }
    };

    timer = new Timer(0, action);
    timer.start();
}
4

3 に答える 3

2

ここに画像の説明を入力

これは、時間の経過とともに更新できるレンダリング可能なアーティファクトのリストを使用する基本概念の例です。

基本的な考え方は、レンダリングしたいものに基づいて UI の現在の状態を更新する役割を担う中央ペイント ループがあるということです。これは、UI へのすべての変更がこの中央ループを通過する必要があることを意味します。

この例では Swing のみを使用していますが、概念は簡単に翻訳できるはずです。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class QuickPaint01 {

    public static void main(String[] args) {
        new QuickPaint01();
    }

    public QuickPaint01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Environment {

        private List<Drawable> drawables;

        public TestPane() {
            drawables = new ArrayList<>(25);
            Timer update = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Drawable[] draws = drawables.toArray(new Drawable[drawables.size()]);
                    for (Drawable drawable : draws) {
                        if (drawable instanceof Moveable) {
                            ((Moveable)drawable).update(TestPane.this);
                        }
                    }
                    repaint();
                }
            });
            update.setCoalesce(true);
            update.setRepeats(true);
            update.start();
            drawables.add(new Ball());
        }

        @Override
        public void add(Drawable drawable) {
            drawables.add(drawable);
        }

        @Override
        public void remove(Drawable drawable) {
            drawables.remove(drawable);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Drawable drawable : drawables) {
                drawable.draw(this, g2d);
            }
            g2d.dispose();
        }
    }

    public interface Environment {

        public Dimension getSize();
        public void add(Drawable drawable);
        public void remove(Drawable drawable);

    }

    public interface Drawable {

        public void draw(Environment env, Graphics2D g);

    }

    public interface Moveable extends Drawable {

        public void update(Environment env);

    }

    public class Ball implements Moveable {

        private int radius = 20;

        private int x = 0;
        private int y = 0;

        private int xDelta = 4;

        private Shape shape;

        public Ball() {
            shape = new Ellipse2D.Float(0, 0, radius, radius);
        }

        @Override
        public void update(Environment env) {
            x += xDelta;
            if (x + radius > env.getSize().width) {

                x = env.getSize().width - radius;
                xDelta *= -1;

                env.add(new Message(env, "<< Bounce", 1));

            } else if (x < 0) {

                x = 0;
                xDelta *= -1;

                env.add(new Message(env, "Bounce >> ", 1));

            }
            y = (env.getSize().height - radius) / 2;
        }

        @Override
        public void draw(Environment env, Graphics2D g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.translate(x, y);
            g2d.setColor(Color.BLUE);
            g2d.fill(shape);
            g2d.dispose();
        }

    }

    public class Message implements Drawable {

        private Environment environment;
        private String message;
        private int delay;

        public Message(Environment environment, String message, int delay) {
            this.environment = environment;
            this.message = message;
            this.delay = delay;

            Timer timer = new Timer(delay * 1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Message.this.environment.remove(Message.this);
                }
            });
            timer.start();
        }

        @Override
        public void draw(Environment env, Graphics2D g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            FontMetrics fm = g2d.getFontMetrics();
            g2d.drawString(message, env.getSize().width - fm.stringWidth(message), 0 + fm.getAscent());
            g2d.dispose();
        }

    }

}
于 2013-07-10T05:06:36.470 に答える
0

疑似コードで記述されているため、いくつかの部分を使用してソリューションを構築できます。

  • saveMessageIsVisibleに設定されているフィールドを導入するfalse
  • キー処理方法の内部
    • ゲームの状態を複製する
    • 新しいスレッドを開始し、状態を保存します
    • このスレッドの最後で、saveMessageIsVisibletrue に設定します (オプションで無効化画面を実行します) 。
    • また、2 秒のタイマーを開始してから、フィールドを再度 false に設定します。
  • ペイント ルーチン内でフィールドをチェックし、セーブ ボックスを描画します。
于 2013-07-10T04:40:12.040 に答える
0

一定期間タスクを実行するには、次のようにします。

ExecutorService service = Executors.newSingleThreadExecutor();
try {
    Runnable r = new Runnable() {
       @Override
       public void run() {
         // task
       }
    };

    Future<?> f = service.submit(r);

    f.get(2, TimeUnit.MINUTES);     // attempt the task for two minutes
} catch (Exception e) {
     //Handele Exception
} finally {
     service.shutdown();
}
于 2013-07-10T04:56:11.323 に答える