4

そこで人気のゲームポンをJavaで作ろうとしています。プレーヤーを四角形にしてアクション リスナーをセットアップしたので、プレーヤーを画面上で上下に移動する準備が整いました。しかし、私は問題に遭遇しました。プレーヤーを動かしているとき、移動ごとに X ピクセルを移動する選択肢があります。

しかし、移動する X ピクセルを 1 に設定すると、プレーヤーの移動が遅すぎます。X ピクセルを 10 に設定すると、彼は 9 ピクセルをスキップし、アニメーションが粗くなります。どうすればアニメーションを滑らかにしながら速く動くことができますか?

ここにいくつかのコードがあります:

public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == keyUp){
                    playerYCordinate -= 10;
                }else if(e.getKeyCode() == keyDown){
                    playerYCordinate += 10;
                }
                repaint();
            }

            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == keyUp){

                }else if(e.getKeyCode() == keyDown){

                }
                repaint();
            }
4

5 に答える 5

4

システムが提供するキーリピート機能に依存しないでください。これらは低レートで発生する可能性があり(これにより、説明する問題が発生します)、システムのキーボード設定によって異なります。

keyPressedを開始TimerおよびkeyReleased停止するために使用することをお勧めします。

タイマーは、TimerTask20ミリ秒ごとに実行するようにスケジュールできます。これにより、座標が更新され、が呼び出されますrepaint()。(頻繁に呼び出すことを心配する必要はありませんrepaint()。EDTが追いつかない場合は、連続する呼び出しが折りたたまれて1つのペイントに再ペイントされます。)

于 2012-06-11T09:38:50.420 に答える
2

どうすればアニメーションをスムーズにし、それでも速く動くことができますか?

1つの手法は、移動するオブジェクトの半透明バージョンを、1回の移動あたりのステップ数が少ない場合のパスに沿ってペイントすることです。

たとえば、10ピクセルの移動の場合、移動の1番目のピクセルの不透明度が10%、2番目のピクセルの不透明度が20%のバージョンを描画します。

移動閉塞

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class MovingBlock {

    MovingBlock() {
        final JPanel gui = new JPanel() {

            private static final long serialVersionUID = 1L;
            int x = 0;
            int step = 60;

            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D)g;
                x+=10;
                Color fg = getForeground();
                for (int ii=x-step; ii<x; ii+=4) {
                    double transparency = (double)(x-ii)/(double)step;
                    Color now = new Color(
                            fg.getRed(),
                            fg.getGreen(),
                            fg.getBlue(),
                            (int)(255*(1-transparency)));
                    g2.setColor(now);
                    g2.fillRect(ii, 3, 5, 10);
                }
                if (x>getWidth()) {
                    x=0;
                }
            }
        };
        gui.setBackground(Color.BLACK);
        gui.setForeground(Color.GREEN.darker());
        gui.setPreferredSize(new Dimension(400,16));

        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                gui.repaint();
            }
        };
        Timer timer = new Timer(20, listener);
        timer.start();

        JFrame f = new JFrame("Moving Block");
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setContentPane(gui);
        f.pack();
        f.setLocationByPlatform(true);
        f.setVisible(true);
    }

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MovingBlock();
            }
        });
    }
}
于 2012-06-11T09:37:54.760 に答える
2

ゲームでは、Swing を駆動するイベント ドリブン システムではなく、ゲーム ループを使用してアプリケーションを制御するのが伝統的です。

パドルの動きを格納する変数を持つことができUPます。キー リスナーがこの変数の値を設定すると、ゲーム ループが変数をチェックし、それに応じてパドルの位置を更新します。DOWNSTATIONARY

この手法は、アプリケーションの速度とそれが実行される環境の速度を切り離します。

于 2012-06-11T10:25:21.800 に答える
1
  • KeyListenerには使用しないでくださいSwing JComponents

  • キーバインディングを使用するSwing JComponents

  • JFrameそこに塗らないで の代わりにJPanelメソッドを使用すると、動きがスムーズで自然になりますpaintComponent()paint()

于 2012-06-11T10:25:06.793 に答える
0

四角形の制御をキーの押下に依存している限り、キーリピート イベントが発生したとき (またはユーザーが入力できるとき) にしか移動できません。マウスの動きなどを聞くか、キーボードのリピート レートを高く設定します。

于 2012-06-11T09:39:34.023 に答える