我目前正在基於超級馬里奧兄弟的一個小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);
}
}
}
謝謝您的回答。 我刪除了gameRender和gamePaint方法,並試圖做你的建議,但我真的不知道我應該在哪裏放置這些方法和哪些參數使用,我真的不熟悉重繪,我不知道如何應用你給我的鏈接的解釋...我試圖把重繪()在窗口的更新方法,我刪除 this.pan.render(); this.pan.paintComponent(getGraphics()); 但現在模型運行,但沒有任何顯示在JFrame上......那麼我需要做什麼?放置一個super.PaintComponent?哪裏和哪些參數? – user3630007
首先,閱讀鏈接教程。你不控制油漆過程。您可以簡單地在'Panel'上調用'repaint'來請求重新繪製組件。在將來的某個時候,paintComponent將被調用,當它是時,你只需重新繪製整個場景。首先調用'super.paintComponent',在你做其他任何事情之前,這將消除可能出現的骯髒的塗料或油漆假象 – MadProgrammer
@ user3630007你也可以考慮看看[這個例子](http://stackoverflow.com/questions/23619540)/java-thread-and-graphics2d/23620125#23620125)其中介紹了一個簡單的MCV實現動畫一個簡單的對象的實現 – MadProgrammer