2011-11-28 20 views
1

私はSpacePotaters(JFrameのサブクラス)と呼ばれるトップレベルのGUIクラスを持っており、そのコンテンツペインにpanelViews(CardLayoutレイアウトマネージャを使用する)というJPanelを追加します。とりわけ、私はPanelViewにカードとしてMainMenuオブジェクト(JPanelのサブクラス)とGameViewオブジェクト(JPanelのサブクラス)を追加します。その便利な場合CardLayoutに間違ったJPanelが表示されます。

public SpacePotaters(){ 
    super("Space Potaters"); 
    Container content = getContentPane(); 

    // initialize components 
    gameView = new GameView(this); 
    mainMenu = new MainMenu(this); 
    leaderboard = new Leaderboard(this); 
    instructions = new JPanel(); // to do 
    cLayout = new CardLayout(); 

    // add "cards" to CardLayout manager 
    panelViews = new JPanel(cLayout); 
    panelViews.setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT)); 
    panelViews.add("gameView", gameView); 
    panelViews.add("mainMenu", mainMenu); 
    panelViews.add("leaderboard", leaderboard); 
    panelViews.add("instructions", instructions); 

    // initially display menu menu 
    content.add(panelViews); 
    cLayout.show(panelViews,"mainMenu"); 

    addWindowListener(this); 
    pack(); 
    setResizable(false); 

    // relocate window to center of screen 
    setLocationRelativeTo(getRootPane()); 
} 

、メインメニューの塗装方法はここにある:

@Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.drawImage(mainMenuBackground, 0, 0, spTop.getWindowWidth(), spTop.getWindowHeight(), null); 

} 

今私はちょうど背景画像を描く - 後で私がクリックしたときには、別のカードに切り替えるということJButtonがを追加します。

私は、メインメニューカードから始め、必要に応じて他のカードに切り替えることを考えています。私はプログラムを実行し、メインメニューのカードが一時的に点滅してから、gameView用に作成されたイメージに置き換えられていることに気付きました。実際にそのカードに切り替えるまでgameViewのグラフィックをレンダリングするのを待たなければならないことがわかっているので、ゲームが早期に開始されることはありません。それは私が混乱するところではない。私が待っていなくても、gameViewはそれを見ることができずに起動してはいけませんか?言い換えれば、mainMenuは、gameViewの内部で何が起こっているかにかかわらず、唯一の目に見えるカードではないでしょうか?

問題は、アクティブなレンダリングとダブルバッファリングを使用するgameView内のものだとわかりました。 GameViewは、ゲームの回ループと呼ばれるこの方法た:このメソッドの本体をコメントアウト

public void paintScreen(){ 
    // get fresh graphics context for GameView each time 
    Graphics context = getGraphics(); 
    if (context != null && dbImage != null){ 
     context.drawImage(dbImage, 0, 0, null); 
    } 
    context.dispose(); 
} 

は、所望の結果を生成する - だけはmainMenuが示されています。私はなぜこれが当てはまるのか混乱しています。私は、各コンポーネント(JFrame、JPanelなど)に独自のグラフィックスコンテキストがあると思っていました。したがって、GameView内でgetGraphics()を呼び出すと、spTopまたはpanelViewsのグラフィックスコンテキストではなく、gameViewパネルのグラフィックスコンテキストが返されるべきではありませんか?また、特定のグラフィックスコンテキストのみを変更するため、gameViewパネルが表示されていない場合(mainMenuオブジェクトでCardLayoutのshow()メソッドを使用していてはいけません)、メインメニューのビューには影響しません。何か案は?

注:gameViewとmainMenuの両方をisVisible()でテストすると、gameViewはfalseを返し、mainMenuはtrueを返します。また、getMraphics()を使用して、mainMenu、spTop、およびgameViewのグラフィックスコンテキストがすべて異なっているかどうかをテストしました。 gameViewはそれ自身のグラフィックスコンテキスト上に画像を描画しており、表示されません。paintScreen()内のdrawImage()の効果はまだです!本当に混乱しています。

+1

すぐに役立つように、[SSCCE](http://sscce.org/)を投稿してください。 –

+0

gameViewがアクティブなカードの前にpaintScreen()を呼び出すコードがありますか? GameViewがパネルを表示しているかどうかにかかわらず、そのメソッドがゲーム画面をペイントするように見えます。 –

+1

カスタムペイントにはgetGraphics()を使用しないでください。絵は一時的なものです。 JComponentまたはJPanelのpaintComponent()メソッドをオーバーライドします。 – camickr

答えて

0

何が起こっているのか理解しようとすると、埋め込みグラフィックスコンポーネント内でアクティブなレンダリングが少なくともそのコンポーネントの可視性は無視されます。したがって、paintScreen()内のdrawImage()は、呼び出されたJPanelが可視かどうかに関係なく、常に可視の結果を表示します。

私は完全にはわかりませんが、この混乱はアクティブなレンダリングとパッシブレンダリングを混在させようとしていると考えられます。 mainMenuはpaintComponent()をオーバーライドし、パッシブレンダリングを使用してペイントします。私のgameViewの可視性をfalseに設定すると、トップレベルのJFrameは単にgameViewのpaintComponent()を呼び出さないことがあります。しかし、gameViewはpaintScreen()で描画するので、その可視性をfalseに設定しても動作には影響しません。これは私がこれに関する具体的な情報を見つけることができなかったので、実験に基づくすべての推測です。

また、BufferStrategyを使用してアクティブなレンダリングを実行しようとすると、同じ結果が得られるかどうかはわかりません(つまり、BufferStrategyのshow()が関連するグラフィックスコンポーネントの可視性を無視し、可視のスクリーンに描画する場合)。それはまだ調査する必要があるものです。

この理解を私の現在のプログラムとどのように調和させるかについては、すべてを書き直したくないので、私はハイブリッドアプローチを使うことに決めました。私は、PanelViews/"cards"(CardLayoutを使用)を切り替えるためにパッシブレンダリングを使用します。私がgameViewに切り替えるときだけ、そのアクティブレンダリング動作をオンにします。終了して別のカードに戻ると、私はgameViewのアクティブレンダリングをオフに戻します。パッシブで能動的なレンダリングのミキシングはお勧めできませんが、両方の戦略を同時に使用することはないため、問題は発生しないことを願っています。このアプローチは現在、mainMenuとgameViewの間で切り替えるために機能するので、他の受動的にレンダリングされたコンポーネントを追加すると動作すると思います。

関連する問題