尽管有BufferedReader,但由于背景重绘而闪烁

时间:2014-05-12 20:47:56

标签: java user-interface background flicker

我目前正致力于基于超级马里奥兄弟的小型2D游戏。 我正在使用模型 - 视图 - 控制器 - 模式,我的面板中有一个闪烁的问题(扩展JPanel)。我的积木和马里奥的一切都在不断闪烁,我不知道为什么。我试图做一个BufferedReader来解决这个问题,但它没有改变任何问题,也没有更小的分辨率背景。 我注意到当我移除背景时(所以我们看到马里奥留下的痕迹),没有任何闪烁,但我不能让它像那样...... 你对问题出在哪里有什么想法吗?

非常感谢您的关注,我在这里加入了我的GUI代码。

PS:我是java的新手,请原谅我的初学者代码和问题:)。另外,请原谅我的英语。如果需要,我可以添加我的代码的任何其他部分。

注意:level是我的主要模型循环,并且有不同的奖励与Mario的不同效果作为不同的状态,如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);
    }

}

}

1 个答案:

答案 0 :(得分:0)

  • 请致电super.painComponent
  • 不要使用getGraphics,它可以为null并且可以被paint子系统覆盖
  • 不需要gameRender方法,Swing组件已经双重缓冲。

您似乎认为可以在Swing中控制绘制过程。 Swing使用被动绘画过程,这意味着在没有您参与的情况下,可以在任何时候出于任何原因多次更新油漆。

您可以使用repaint请求更新,但是应该由paint子系统来安排并在实现更新时实际执行更新

看看

了解更多详情

摆脱您的gameRendergamePaint方法,只需在面板上调用repaint即可更新其输出