2

私は Java で小さなゲームを開発しており、プレイヤー移動システムをグリッドベースにならないように書き直しています。これは 2D サイド スクローラーであり、私が達成しようとしているのは基本的なプレーヤーの動きです。ユーザーが押したままにすると、プレーヤーは右のキーを右に移動し、左のキーも同じように移動します。私が抱えている問題は、別のクラスの Paint コンポーネントが、設定クラスに格納されている位置 X と Y を使用して、画面にプレーヤーの画像を描画することです。次に、ユーザーが右を押すと KeyListener クラスが取得され、X 値に追加されます (左も同じですが、毎回マイナス 1 になります)。これにより、画面上でゆっくりと動くキャラクターが作成されます。私がやりたいのは、ピクセルをスキップしているように見えるため、毎回 1 ピクセル以上追加することなく、キャラクターをより速く移動させることです (私は既に試しました)。

私が使用しているコードは最低限のものであり、私の結果は滑らかに動くプレーヤーになるので、これについてもっと良い方法があるかどうか疑問に思っていました。

KeyListener スニペット:

public void keyPressed(KeyEvent arg0) {
    int key = arg0.getKeyCode();

    if(key == 39) { // Right Key
        Settings.player_pos_x++;
    }else if(key == 37) { // Left Key
        Settings.player_pos_x--;
    }

    main.Game.redo();
}

画面上のユーザーの描画:

g.drawImage(player_image, Settings.player_pos_x, Settings.player_pos_y, this);

さらに情報やコードが必要な場合は、お気軽にお問い合わせください。

4

4 に答える 4

3

もう一度試してみましょう:)

ダブルバッファリング

引用: http: //msdn.microsoft.com/en-us/library/b367a457.aspx

ちらつきは、グラフィックをプログラミングするときによくある問題です。複数の複雑なペイント操作を必要とするグラフィックス操作により、レンダリングされた画像がちらついたり、他の方法では許容できない外観になる可能性があります。

ダブルバッファリングが有効になっている場合、すべてのペイント操作は、画面上の描画面ではなく、最初にメモリバッファにレンダリングされます。すべてのペイント操作が完了すると、メモリバッファはそれに関連付けられた描画面に直接コピーされます。画面上で実行されるグラフィック操作は1つだけであるため、複雑なペイント操作に関連する画像のちらつきがなくなります。

引用:http ://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html

画面上にピクセルごとまたは行ごとに画像全体を描画する必要があるとします。そのようなものを画面に直接描画する場合(たとえば、Graphics.drawLineを使用して)、少し時間がかかることに多くの失望を覚えるでしょう。あなたはおそらくあなたの絵がどのように描かれているかの目に見えるアーティファクトにさえ気付くでしょう。ほとんどのプログラマーは、この方法でこのペースで描画されるものを見るのではなく、ダブルバッファリングと呼ばれる手法を使用します。

于 2012-04-20T20:24:09.407 に答える
1

ダブルバッファリングはおそらくあなたが毎回移動する距離を計算する方法に最初に取り組むべきであるのを助けるでしょうが。

距離の変化(dx)は、速度(v)に時間の変化(dt)を掛けたものとして定義できます。dx= v*dt。私が見ることができることから、あなたはdt(時間の変化)を省略していることがわかります。キャラクターが最後に動かされたときからの時間差を計算し、それに速度を掛ける必要があります。このように、距離処理コードが10回または10秒間に100回実行された場合、キャラクターは常に同じ距離を移動します。

コードは次のようになります。

int currentTime = System.nanoTime();
int deltaTime = currentTime - previousTime;

Settings.player_pos_x += velX * deltaTime;

previousTime = currentTime;

このコードを使用すると、おそらくvelXを大幅に増やす必要があります。通常、私は速度を掛ける定数を持っているので、それらはより小さな数になります。

さらに、より良い動きと物理学が必要な場合は、JBox2Dを調べてください。ただし、現時点ではおそらくやり過ぎです。彼らのドキュメントは、基本的な物理学を理解するのにも役立つかもしれません。

于 2012-04-20T21:19:37.777 に答える
1

おそらく、アプリを作成して、右への複数の再描画を繰り返すことができます。各再描画は、受信したキーボード入力ごとに1ピクセルまたは2ピクセルだけです。このようにして、移動速度を人為的に設定します。そうしないと、ユーザーがキーボードの反復速度を設定する方法に制限されます。

また、javaのjPanelは、ビデオゲームの効率を探す場所ではありません。ただ言って; そのためにopenGLのようなものを探したいと思うかもしれません。

せいぜい、jPanelと同じ描画機能を使用して、jpanel描画ロジックの外部に遷移バッファーを含めるように最適化できます。このようにして、バッファーに書き込み、writeImage呼び出し中にバッファー全体をコピーします...私はしませんすでにそれを行っているかどうかはわかりませんが、ちらつきなどを回避できると思います...ずっと前に読んで、ダブルバッファリングと呼ばれています。

于 2012-04-20T20:22:48.153 に答える
0

速度に関する質問に答えるために、私が見たほとんどのゲームは、各平面(x平面とy平面)の速度のグローバルintを格納し、速度を単純にインクリメントするのではなく、現在の位置に適用します。その上。

public int velX = 2;
public int velY = 2;

public void keyPressed(KeyEvent arg0) { 
    int key = arg0.getKeyCode(); 

    if(key == 39) { // Right Key 
        Settings.player_pos_x += velX; 
    }else if(key == 37) { // Left Key 
        Settings.player_pos_x -= velX; 
    } 

    main.Game.redo(); 
} 

設定が完了したら、ベロシティを上げる可能性のある操作を追加してみてください(つまり、キーを長時間押し続けるなど)。

また、プレイヤーのY位置が上がるジャンプ操作を実装し、重力場を追加して元に戻すようにします。

于 2012-04-20T20:39:14.503 に答える