2014-05-12 55 views
0

我目前正在基於超級馬里奧兄弟的一個小2D遊戲 我正在使用模型 - 視圖 - 控制器模式,我在我的面板中有一個閃爍的問題(擴展的JPanel)。我的街區和除馬里奧以外的所有街區都在不斷閃爍,我不知道爲什麼。我試圖做一個BufferedReader來解決這個問題,但它並沒有改變任何問題,也沒有一個更小的分辨率背景。 我注意到,當我刪除背景(所以我們看到馬里奧留下的痕跡),沒有閃爍了,但我不能讓它這樣... 你有什麼想法,問題出現在哪裏?儘管BufferedReader背景重繪導致閃爍

非常感謝您的關注,我在此加入我的GUI代碼。

PS:我是新來的java,所以請原諒我的初學者代碼和問題:)。另外,請原諒我的英語。如果需要,我可以添加我的代碼的任何其他部分。

注:級別是我的主要模式循環並沒有對馬里奧型動物的影響不同的獎金,就像型動物OnAir公司狀況等

窗口

package GUI; 
import java.awt.Color; 
import java.awt.Component; 
import javax.swing.JFrame; 
import model.Level; 
import observable.Observator; 

public class Window extends JFrame implements Observator{ 

public Panel pan; 
Level level; 

public Window(Level level){ 
    setVisible(true); 
    setTitle("Mario"); 
    setExtendedState(6); 
    setDefaultCloseOperation(3); 
    setLocationRelativeTo(null); 
    setSize(level.cam.getHitboxx(),level.cam.getHitboxy()); 
    setResizable(false); 
    this.level = level; 
    this.pan = new Panel(level); 
    setContentPane(this.pan); 
    } 

public void update(Level level){ 
this.level = level; 
this.pan.setLevel(this.level); 
this.pan.render(); 
this.pan.paintComponent(getGraphics()); 
} 

public Level getLevel() { 
return level; 
} 

public void setLevel(Level level) { 
this.level = level; 
} 

}

面板

package GUI; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import model.Edge; 
import model.Level; 
import model.Mario; 
import model.StaticEntity; 

public class Panel extends JPanel{ 

protected Level level; 
private Image marioNormalLeftImg; 
private Image marioNormalRightImg; 
private Image marioJumpingRightImg; 
private Image marioJumpingLeftImg; 
private Image marioCrouchRightImg; 
private Image marioCrouchLeftImg; 
private Image marioDeadImg; 
private Image backgroundImg; 
private Image rightGoombaImg; 
private Image leftGoombaImg; 
private Image brickImg; 
private Image CoinImg; 
private Image gameOverImg; 
private Image winImg; 
private Image WeedGIF; 
private Image WeedBonusImg; 
private Image metalShroomImg; 
private Image lifeShroomImg; 
private Image shroomImg; 
private Image marioGIF; 
private Image bonusBrickImg; 
private Image groundImg; 

public Panel(Level level){ 
    try 
    { 

     this.marioNormalLeftImg = ImageIO.read(new File("Mario_NormalLeft.png")); 
     this.marioNormalRightImg = ImageIO.read(new File("Mario_NormalRight.png")); 
     this.marioJumpingRightImg = ImageIO.read(new File("Mario_JumpRight.png")); 
     this.marioJumpingLeftImg = ImageIO.read(new File("Mario_JumpLeft.png")); 
     this.marioCrouchRightImg = ImageIO.read(new File("Mario_CrouchRight.png")); 
     this.marioCrouchLeftImg = ImageIO.read(new File("Mario_CrouchLeft.png")); 
     this.marioDeadImg = ImageIO.read(new File("Mario_Dead.png")); 
     this.backgroundImg = ImageIO.read(new File("Background2.png")); 
     this.rightGoombaImg = ImageIO.read(new File("goomba1.png")); 
     this.leftGoombaImg = ImageIO.read(new File("goomba2.png")); 
     this.brickImg = ImageIO.read(new File("Brick_Block.png")); 
     this.bonusBrickImg = ImageIO.read(new File("Bonus_Block.png")); 
     this.CoinImg = ImageIO.read(new File("Coin1.png")); 
     this.gameOverImg = ImageIO.read(new File("GameOver.png")); 
     this.winImg = ImageIO.read(new File("youwin.png")); 
     this.WeedGIF = this.getToolkit().createImage("Weed_Background.gif"); 
     this.marioGIF = this.getToolkit().createImage("walkinggif.gif"); 
     this.WeedBonusImg = ImageIO.read(new File("Weed.png")); 
     this.metalShroomImg = ImageIO.read(new File("metalShroom.png")); 
     this.lifeShroomImg = ImageIO.read(new File("Green_Mushroom.png")); 
     this.shroomImg = ImageIO.read(new File("Red_Mushroom.png")); 
     this.groundImg = ImageIO.read(new File("ground_large.png")); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

    this.level = level; 

} 


public void setLevel(Level level){ 
this.level = level;} 


public void paintComponent(Graphics g){ 
    if(this.level.getTHCratio()>0){g.drawImage(this.WeedGIF, 0, 0, this.level.cam.getHitboxx(), this.level.cam.getHitboxy(), this); 
    } 
    else{g.drawImage(this.backgroundImg, 0, 0, this.level.cam.getHitboxx(), this.level.cam.getHitboxy(), this);} 
    this.paintMario(g); 

    for(int i = 0;i<this.level.goombas.size();i++){ 
    if(this.level.goombas.get(i)!=null){this.paintGoomba(g, i);}} 

    for(int i = 0;i<this.level.edges.size();i++){ 
     if(this.level.edges.get(i)!=null&&this.level.edges.get(i).visible){ 
      if(this.level.edges.get(i).type == "Normal"){ 
       drawComponent(this.level.edges.get(i),this.brickImg,0,g); 
      } 
      else if(this.level.edges.get(i).type == "Ground"){drawComponent(this.level.edges.get(i),this.groundImg,0,g);} 
      else{drawComponent(this.level.edges.get(i),this.bonusBrickImg,0,g);} 
     }  
    } 
for(int i = 0;i<this.level.bonus.size();i++){ 
     if(this.level.bonus.get(i)!=null){ 
      if(this.level.bonus.get(i).getClass().getName() == "model.Coin"){ 
      drawComponent(this.level.bonus.get(i),this.CoinImg,0,g);} 
      else if (this.level.bonus.get(i).getClass().getName() == "model.WeedBonus"){ 
       drawComponent(this.level.bonus.get(i),this.WeedBonusImg,0,g); 
      } 
      else if (this.level.bonus.get(i).getClass().getName() == "model.MetalShroom"){ 
       drawComponent(this.level.bonus.get(i),this.metalShroomImg,0,g); 
      } 
      else if (this.level.bonus.get(i).getClass().getName() == "model.LifeShroom"){ 
       drawComponent(this.level.bonus.get(i),this.lifeShroomImg,0,g); 
      } 
      else if (this.level.bonus.get(i).getClass().getName() == "model.Shroom"){ 
       drawComponent(this.level.bonus.get(i),this.shroomImg,0,g); 
      } 
} 
} 

Font police = (new Font("Mario Kart DS", Font.PLAIN, 30)); 
if (police == null) {police = (new Font("Times New Roman", Font.PLAIN, 30));} 
g.setFont(police); 
g.setColor(Color.white); 
g.drawString("coins " + String.valueOf(this.level.player.getCoins()), 1000, 50); 
g.drawString("score " + String.valueOf(this.level.player.getScore()), 1000, 100); 
g.drawString("lives " + String.valueOf(this.level.player.getLives()), 1000, 150); 

if(level.player.getLives() == 0){ 
    this.backgroundImg = this.gameOverImg;} 
if(this.level.player.getScore() == 200*level.goombas.size() + 100*level.bonus.size()){this.backgroundImg = this.winImg;this.leftGoombaImg = null;this.rightGoombaImg = null;this.brickImg = null;this.level.mario.setPosx(3000);this.level.mario.setPosy(3000);this.CoinImg = null;}   

} 


public void paintMario(Graphics g){ 
    String statusName = this.level.mario.getStatus().getName(); 
    boolean goingRight = this.level.mario.getSpeedx()>=0; 
    if(statusName == "OnAir"){ 
     if(goingRight){drawComponent(this.level.mario,this.marioJumpingRightImg,0,g);    
     }else{drawComponent(this.level.mario,this.marioJumpingLeftImg,0,g);} 
    } 
    else if(statusName == "DEAD"){ 
     drawComponent(this.level.mario,this.marioDeadImg,0,g);    
    } 
    else if(statusName == "Crouch"){if(goingRight){drawComponent(this.level.mario,this.marioCrouchRightImg,0,g);    
    }else{drawComponent(this.level.mario,this.marioCrouchLeftImg,0,g);}} 
    else{ 
     if(goingRight){drawComponent(this.level.mario,this.marioNormalRightImg,0,g);} 
     else{drawComponent(this.level.mario,this.marioNormalLeftImg,0,g);} 
    } 
} 

public void paintGoomba(Graphics g, int i){ 
    boolean goingRight = this.level.goombas.get(i).getSpeedx()>=0; 
    if(goingRight){drawComponent(this.level.goombas.get(i),this.rightGoombaImg,10,g);} 
    else{drawComponent(this.level.goombas.get(i),this.leftGoombaImg,10,g);} 
} 

private Image bufferImage = null; 
private void gameRender() 
{ 
    if(bufferImage == null) 
    { 
     bufferImage = createImage(1200, 800); 
    } 

    Graphics dbg = bufferImage.getGraphics(); 
    this.paintComponent(dbg); 

} 

private void gamePainting() 
{ 
    Graphics g = this.getGraphics(); 
    if((g != null) && (bufferImage != null)) 
    { 
     g.translate(0,0); 
     g.drawImage(bufferImage, 0, 0, null); 
     g.dispose(); 
    } 
} 

public void render() { 
    // TODO Auto-generated method stub 
    this.gameRender(); 
    this.gamePainting(); 

} 
public void drawComponent(StaticEntity obj, Image img,int shapeCorrector,Graphics g){ 
    if(this.level.cam.isOnHitbox(obj.getPosx(),obj.getPosy(),obj.getHitboxx(),obj.getHitboxy())){ 
     g.drawImage(img, obj.getPosx()-shapeCorrector-this.level.cam.getPosx(), obj.getPosy()-shapeCorrector-this.level.cam.getPosy(), obj.getHitboxx()+shapeCorrector, obj.getHitboxy()+shapeCorrector, null); 
    } 

} 

}

回答

0
  • 不要叫super.painComponent
  • 不要使用getGraphics,它可以爲空,可以通過塗料子系統
  • 沒有必要爲gameRender方法,Swing組件都已經被覆蓋雙緩衝。

您似乎認爲您可以控制Swing中的繪製過程。 Swing使用被動繪畫過程,這意味着繪畫更新可能隨時出於任何原因,多次,無需您的參與。

,您可以要求使用repaint的更新,但它是由油漆子系統來安排,當它需要它應該做

看看

更多細節

擺脫你的gameRendergamePaint方法和簡單的調用repaint在面板上,當你想更新其輸出

+0

謝謝您的回答。 我刪除了gameRender和gamePaint方法,並試圖做你的建議,但我真的不知道我應該在哪裏放置這些方法和哪些參數使用,我真的不熟悉重繪,我不知道如何應用你給我的鏈接的解釋...我試圖把重繪()在窗口的更新方法,我刪除 this.pan.render(); this.pan.paintComponent(getGraphics()); 但現在模型運行,但沒有任何顯示在JFrame上......那麼我需要做什麼?放置一個super.PaintComponent?哪裏和哪些參數? – user3630007

+0

首先,閱讀鏈接教程。你不控制油漆過程。您可以簡單地在'Panel'上調用'repaint'來請求重新繪製組件。在將來的某個時候,paintComponent將被調用,當它是時,你只需重新繪製整個場景。首先調用'super.paintComponent',在你做其他任何事情之前,這將消除可能出現的骯髒的塗料或油漆假象 – MadProgrammer

+0

@ user3630007你也可以考慮看看[這個例子](http://stackoverflow.com/questions/23619540)/java-thread-and-graphics2d/23620125#23620125)其中介紹了一個簡單的MCV實現動畫一個簡單的對象的實現 – MadProgrammer