我目前正致力于基于超级马里奥兄弟的小型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);
}
}
}
答案 0 :(得分:0)
super.painComponent
getGraphics
,它可以为null并且可以被paint子系统覆盖gameRender
方法,Swing组件已经双重缓冲。您似乎认为可以在Swing中控制绘制过程。 Swing使用被动绘画过程,这意味着在没有您参与的情况下,可以在任何时候出于任何原因多次更新油漆。
您可以使用repaint
请求更新,但是应该由paint子系统来安排并在实现更新时实际执行更新
看看
了解更多详情
摆脱您的gameRender
和gamePaint
方法,只需在面板上调用repaint
即可更新其输出