2012-03-12 8 views
1

私はこの質問の目的のために、JPanel(GamePanel)を拡張するクラスを追加するJFrameを拡張するクラスを持つゲームを作っています。 GamePanelでは私は2つの関数update()を持つrunメソッドを持っています。とrepaint(); Thread.sleep(20)を呼び出します。更新機能は約1〜2msかかる。私はpaintComponent(Graphics g)に私の描画のすべてを持っています。これは、画面上に何かが表示されてからrepaint()を使うと正しく呼び出されるようです。低い計算で低いfps Java paintcomponent

私の問題は、それは不条理に遅れているということです。私がThread.sleep(20)を持っていなかったとき、それは2fpsのようにunplayableでした。私は、これは、repaint()が完了するのに十分な時間を与えられていなかったか、何か、次のループの前に遅延を追加したことが原因であると読んでいます。 20ms以上またはそれ以下のものは、それをより遅くするようです。

私はグラフィックス構成のものを使用しようとしました、ダブルバッファリングとそれ以上ですが、それは遅いままです。私の家庭のPC、Intel i5、クアッドコア、3.2GHzで約100fpsしか得られず、学校コンピュータでは約15fps(ok pc、amd dual coreのようなものだと思う)だ。 paintComponentループは超軽量です!プレイヤーの位置に応じてオフセットをつけたドローマップを作成し、画面の真ん中にプレーヤーを描きます!私は2000x2000、0.8mbの地図を使用しています。 1000x1000への切り替えを試みましたが、0.4mbと違いはありません。これは下降コンピュータ上の比較的素晴らしいコンピュータと15fpsの上で100FPSになり

@Override 
public void paintComponent(Graphics g) { 
    //Rendering settings and stuff 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

    //Draw map  gameMap.gameMap is a bufferedImage 
    g2d.drawImage(gameMap.gameMap, gameMap.x, gameMap.y, null); 
    //Draw health bar 
    g2d.setColor(healthBarColor); 
    g2d.setComposite(alphaHealthBarBackground); 
    g2d.fillRect(100, 19, 200, 23); 
    g2d.setFont(font); 
    g2d.setComposite(alphaNormal); 
    g2d.setColor(healthBarColor); 
    g2d.drawString("HP: ", 20, 40); 
    g2d.fillRect(100, 19, player.health * 2, 23); 

    //Draw player  player.playerImage is a BufferedImage 
    rotatePlayer.setToRotation(rotation, rotationAnchor.x, rotationAnchor.y); 
    rotatePlayer.translate(xResolution/2, yResolution/2); 
    g2d.drawImage(player.playerImage, rotatePlayer, this); 
    g2d.setColor(Color.white); 
} 

:ここ

は、コードです!

+0

「this」はどれくらい大きく塗られていますか? * "降下コンピュータの15fps!" *それが理解できれば、それが地獄に降下しているので、それは地獄に行くからです。 ;) –

+0

まあ、私はあなたが理解している場合は、 "この"塗装されている画面サイズと同じくらい大きいです。アプリケーションはフルスクリーンです。私はツールキットを使ってスクリーンサイズを取得するので、それは1920x1080で、学校では画面が1280x1024だと信じています... ハハ、まともな;)funny Joke ...:P – Opfff

+0

注:1)FPSテストは固定レンダリングサイズ2)質問を編集してスペルを変更することができます。だから、私はあなたの裁量でそれを残すでしょう。 :) –

答えて

0

ゲーム開発では、スイングpaintComponentで巨大な画像を描画することは今までどんなスピードレコードでも勝つとは思っていません。 100 FPSはまだ素晴らしいです(ほとんどのLCDディスプレイのリフレッシュレートよりも約40 FPS高い)。

さらに高速化するためには、使用している描画プリミティブを高速化することが不可欠です。あなたの学校のPCには、必要な2Dアクセラレーションを提供する適切なグラフィックスカードが不足しているだけかもしれません(ブラウザやペイントプログラムなどで、通常の2D操作をどのように行うのか?)

フレームワーク代わりにJOGLのようなOpenGL。別のオプションは、JavaFX 2を試してみることです - それはより良いレンダリングパイプラインを持つかもしれません。

+0

興味深い。私の学校のコンピュータはokグラフィックスカードを持っていると思う。私たちは時々、何の遅れもなくCS1.6をプレイしました。あなたはそれらのHDビデオを再生し、フラッシュゲームやものを再生することができます。私はマルチスレッドのラインでもっと考えていました。私のゲームでは、音楽、衝突の検出、動き、発砲されたショット、マルチプレイヤーのためのUDP情報の送信などのスレッドを使用します。 Graphics2Dはデフォルトでハードウェアアクセラレーションされていますか?私はジョグルとjavafx2をチェックアウトします... – Opfff

4

だけでいくつかのヒント、究極のソリューションを装っていない:

  1. はあなたのバッファリングされた画像は、彼らが描かれているGraphicsDeviceのデフォルトと同じカラーモデルを持っていることを確認してください。メソッドGraphicsConfiguration.createCompatibleImageは、そのような画像を作成する可能性があります。

  2. 可能であれば、巨大なマップ全体をタイルに分割し、オフスクリーン(ゲームビューから外れた)レンダリングをスキップしてみてください。

  3. repaint()の呼び出しのように、パッシブレンダリングを使用しているようです。 Event Dispatch SwingやAWTの多くのもので使用されるスレッドで、活発にレンダリングされるゲームのタイミングを保証するものではありません。おそらく、Active Renderingを使用するためにゲームの一部を再デザインする価値があります。チュートリアルと例はhereです。

+0

答えをありがとう! 1.私は実際にすべてのBufferedImageをImageに変更しました。 + 10 fpsを与えた。あなたがそこで何を意味しているか分かりません。ImageMode = ImageIO.read(新規ファイル(GM)); // GM = String GraphicsConfiguration.createCompatibleImageはどのようにそこに収まるのですか? 2.それはすべて面白いスケールにしました。 fpsゲインはありません 3. XDの痛みですが、g2d.setClip(0,0、screenx、screeny)のアイデアがありました。 + 50fpsを与えます。 160fpsでアップ! :) 4.今すぐお試しください: ありがとう!! – Opfff

+0

私は、ImageIOによって読み取られた画像がターゲットサーフェイスに描画されるときに何らかの変換を必要とすることを意味していました。例えば、私が覚えているように、Windowsプラットフォームでは、['BufferedImage.TYPE_INT_ARGB'](http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage .html#TYPE_INT_ARGB)。 'ImageIO.read'を使ってイメージをロードし、GraphicsConfigurationを通して同じサイズのイメージを作成し、すべてのソースイメージを互換性のあるものにレンダリングします。結果をゲームのレンダリングに使用します。 – Mersenne

+0

そして、間違ったペイントオーバーロードを誤って指摘しました。実際、私はこれを意味しました(http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawImage%28java.awt.Image,%20int,%20int,%20int 、%20int、%20int、%20int、%20int、%20int、%20java.awt.image.ImageObserver%29)バージョンで、画像の一部分を描画することを意図していました。 – Mersenne

0

は、私はまた、Javaのゲームを開発していますし、あなたが同じ多くのことを行っている(JPanelのを延長し、再描画の呼び出し())。 1つの違いは、javax.swing.Timerを使用してActionPerformed(ActionEvent e)メソッドを呼び出し、5msごとに自分のゲームを更新することです。メソッドの終わりに、repaint()を呼び出してレンダリングを行います。

Graphics2Dを使用してレンダリングを行っている場合は、レンダリングヒントを使用してゲームのレンダリング方法(例:スピードまたはクオリティ、そのようなもの)をコンピュータに導くことができます。

私は正確にFPSを測定していないが、私は私のUbuntu 12.10のシステムに何の遅れを取得していないし、Windows 8

に少しだけ遅く、私は私の応答はあなたが何を望むかを正確でない場合は謝罪が、これはありますこれまで私が問題なく動作してきたもの。

関連する問題