Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何停止在使用瓷砖的侧卷轴中闪烁?_Java_Swing - Fatal编程技术网

Java 如何停止在使用瓷砖的侧卷轴中闪烁?

Java 如何停止在使用瓷砖的侧卷轴中闪烁?,java,swing,Java,Swing,因此,我试图阻止我的程序闪烁,但由于其他人的问题,我找不到适用于我的代码的解决方案。它只是闪烁,我看到另一个人的帖子建议改为paintComponent,但与paint相比,我看不出它是如何工作的。任何帮助都将不胜感激 package runalreadypls; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import jav

因此,我试图阻止我的程序闪烁,但由于其他人的问题,我找不到适用于我的代码的解决方案。它只是闪烁,我看到另一个人的帖子建议改为paintComponent,但与paint相比,我看不出它是如何工作的。任何帮助都将不胜感激

package runalreadypls;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;

public class GameGen extends JFrame implements KeyListener{
    private static final long serialVersionUID = -7177541209377865450L;
    Random rand = new Random();//Random generator for map
    double move = 0;//Moves graphics generation 
    int timed = 750;//Moving delay
    int speed = 2;//Moves Faster
    int [][] world=new int[10][100];//Map generation
    int WIDTH = 720;//Width of frame/window
    int HEIGHT = 480;//Height of frame/window
    String exitMSG;//Exit message
    String user;//username
    int charX = 0;//Starting coordinates for character
    int charY= 4;
    BufferedImage img1;//Graphics generation
    static double score = 0;//Score of player
    GameGen(){//Start game
        super("Runner");//Set frame specifications
        this.setSize(WIDTH,HEIGHT);
        this.setLocationRelativeTo(null);
        this.setUndecorated(true);
        this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        this.setResizable(false);
        this.setFocusable(true);
        this.setVisible(true);
        //Adds spacebar listener
        addKeyListener(this); 
        //Starts world generation
        worldGen();
        //Paints world
        repaint();

        //Swing Timer for moving of character and background
        Timer timer = new Timer(timed ,null);
        timer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                //Increasing speed

                if (speed < 400){
                    speed = speed + 5;
                }
                timer.setDelay(timed - speed);
                //Increasing score
                score = score + 3;
                //Moving character
                charX= charX + 1;
                //Checks if game is over
                if(gameOverCollision()){
                    timer.stop();//Ends "delayed loop" 
                }
                //Gravity
                //If charY is not below the screen to prevent array out of bounds
                if (charY < 9){
                    if (world[charY+1][charX] == 0){//Moves character down/Gravity
                        charY = charY+1;
                        deleter();//Deletes character previous coords
                        mover();//Moves character coords on array
                    }
                }
                deleter();//Deletes character previous coords
                mover();//Moves character coords on array
            }
        });

        timer.start();//Starts "delayed loop" / swing timer 
    }
    public void deleter(){//Deletes character previous coords so there is only one character on the screen
        for(int x = 0;x <9;x++){
            for(int y = 0; y < 100; y++){
                if (world[x][y] == 2){
                    world[x][y] = 0;    
                } 

            }
        }

    }

    public void mover(){//Moves character on the array
        world[charY][charX] = 2;
        repaint();
    }

    /*
     * 
     * 0 = Background
     * 1 = Surface
     * 2 = Player
     * 3 = Below Surface
     * 
     * */

    public void worldGen(){
        int xAt = 5;
        world[4][0] = 2;//Character placement
        world[5][0] = 1;//First tile placement
        for (int x = 1; x < 100; x++){  //Starting place
            int X =3;
            X = rand.nextInt(X)+1;//Random Number Generator 
            if (xAt <= 6 && xAt>=3){//If where the ground is at is between 7 and 2 (exclusive)then it will generate normally 
                if (X == 1){
                    xAt =xAt+ 1;
                    world[xAt][x] = 1;
                }else if (X == 3){  
                    xAt =xAt - 1;
                    world[xAt][x] = 1;
                }else if (X==2){
                    world[xAt][x]=1;
                }
                /*
                 * If where the ground is at is too low between 7 and 9 (which is the bottom 3 tiles)
                 * then it will generate with more chances of going up instead of staying the same
                 * 
                */
            }else if(xAt >6 && xAt <9){
                if (X==1 || X==3){
                    xAt =xAt- 1;
                    world[xAt][x] = 1;
                }else if (X==2){
                    world[xAt][x]=1;
                }
                /*
                 * If where the ground is at is too low between 1 and 4((exclusive) which is the top 3 tiles) 
                 * then it will generate with more chances of going down instead of staying the same
                 * 
                */
            }else if(xAt >1 && xAt <3){
                if (X==1 || X==3){
                    xAt =xAt+ 1;
                    world[xAt][x] = 1;
                }else if (X==2){
                    world[xAt][x] = 1;
                }
            }
        }
        //Generates ground below the surface
        for(int x = 0;x <9;x++){
            for(int y = 0; y < 100; y++){
                if (world[x][y] == 1){
                    world[x+1][y] = 3;
                } 
                if (world[x][y] == 3){
                    world[x+1][y] = 3;
                }
            }
        }
    }
    @Override
    public void paint(Graphics g){
        super.paint(g);
        g.setColor(Color.WHITE);
        g.setFont(new Font("TimesRoman", Font.PLAIN, 100)); 
        g.drawString(Integer.toString((int) score), 220, 100);
        //Checks through 2d array to generate images
            for(int x = 0;x <9;x++){
                for(int y = 0; y < 100; y++){
                    if(world[x][y] == 0){
                        try {//If background then accesses background image
                            img1 = ImageIO.read(new File("src/runalreadypls/Background.png"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    } else if(world[x][y] == 1){
                        try {//If surface then accesses surface image
                            img1 = ImageIO.read(new File("src/runalreadypls/Ground.png"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }else if (world[x][y] == 2){ 
                        try {//If surface then accesses character image
                            img1 = ImageIO.read(new File("src/runalreadypls/Character2.png"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }else if (world[x][y] == 3){
                        try {//If below surface then accesses below surface image
                            img1 = ImageIO.read(new File("src/runalreadypls/Foreground.png"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    g.drawImage(img1,(int) (45*(y-move)),60*x,null);//Draws images in procedural order
                }
            }
            move = move + .65;//Moves screen

    }
    /*
     * 
     * WALL collision
     * If player misses jump
     * Game is over
     * 
     * 
     * */
    public boolean gameOverCollision(){
        //Checks if the player has missed a tile or if they have finished the map
        if(world[charY][charX] == 1||charX == 99){
            /*
             * 
             * Adds current players score to the high score file
             * 
             * */
            try {
                fileAppend();
            } catch (IOException e) {
                e.printStackTrace();
            }
            /*
             * 
             * Sorts high scores in order of greatest to least 
             * 
             * */
            try {
                fileSort();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //Deletes window
            dispose();
            //Exit Msg
            exitMSG = "Thank you for playing " +Game.name() +" your score is: " + score;
            JOptionPane.showMessageDialog(null, exitMSG, "Thank you for Playing!", JOptionPane.ERROR_MESSAGE);
            //Recreates main menu
            new Game();
            //Reseting Score and speed
            score = 0;
            speed = 2;

            return true;
            //Checks if player has finished the map
        }else{
            return false;
        }       
    }
    public void fileSort()throws IOException,FileNotFoundException{
        List<Integer> list = new ArrayList<Integer>();//Array list to store integers
        File file = new File("highscores.txt");//File 
        BufferedReader br = null;//br
        br = new BufferedReader(new FileReader(file));//br
        String text = null;//text
        while ((text = br.readLine()) != null) {//Putting integer into list
            list.add((int) Double.parseDouble(text));//Converting line text to int and putting into list
        }
        if (br != null) {//closing
            br.close();
        }
        Collections.sort(list);//sort list
        Collections.reverse(list);//reverse list for descending order
        FileWriter fw = new FileWriter("highscores.txt");//Write to file
        BufferedWriter bw = new BufferedWriter(fw);
        for(Integer lists: list) {
          bw.write(lists);//WRiting to file
          bw.newLine();//New line
        }
        bw.close();//Closing
        fw.close();
    }
    public void fileAppend()throws IOException{
        //Declaring writers
        FileWriter fw = null; 
        BufferedWriter bw = null; 
        PrintWriter pw = null; 
        fw = new FileWriter("highscores.txt", true);
        bw = new BufferedWriter(fw); pw = new PrintWriter(bw); 
        pw.println(score); //Adding to file
        //Closing
        pw.close(); 
        bw.close(); 
        fw.close(); 
    }
    /*
     * 
     * Listens to spacebar input to move character up a tile
     * 
     * */
    @Override
    public void keyPressed(KeyEvent e) {
        if(charY<9 && charY >0){
            if (e.getKeyCode()==KeyEvent.VK_SPACE){
                if(world[charY][charX+1] == 1){
                    charY-=1;//Moving character Y coords up a tile
                    deleter();//Deletes character previous coords
                    mover();//Changing player's tile in array
                }
                if(world[charY][charX+1] != 1){ 
                    score = score -3; //Substracts score if player jumps early  
                }
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {   
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }

}
包runalreadypls;
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入java.awt.image.buffereImage;
导入java.io.BufferedReader;
导入java.io.BufferedWriter;
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileReader;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.io.PrintWriter;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.List;
导入java.util.Random;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JOptionPane;
导入javax.swing.Timer;
公共类GameGen扩展JFrame实现KeyListener{
私有静态最终长serialVersionUID=-7177541209377865450L;
Random rand=new Random();//映射的随机生成器
双移动=0;//移动图形生成
int timed=750;//移动延迟
int speed=2;//移动速度更快
int[][]世界=新int[10][100];//地图生成
int WIDTH=720;//框架/窗口的宽度
int HEIGHT=480;//框架/窗口的高度
字符串exitsg;//退出消息
字符串user;//用户名
int charX=0;//字符的起始坐标
int-charY=4;
BuffereImage img1;//图形生成
静态双倍得分=0;//玩家得分
GameGen(){//开始游戏
super(“Runner”);//设置帧规格
此.setSize(宽度、高度);
此.setLocationRelativeTo(空);
此项。未装饰的设置(正确);
此.setDefaultCloseOperation(在关闭时不执行任何操作);
此参数为.setresizeable(false);
此参数为.setFocusable(true);
此.setVisible(true);
//添加空格键侦听器
addKeyListener(此);
//开始世界新一代
worldGen();
//绘画世界
重新油漆();
//用于移动角色和背景的摆动计时器
计时器=新计时器(已计时,空);
timer.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件evt){
//增长速度
如果(速度<400){
速度=速度+5;
}
定时器。设置延迟(定时-速度);
//增加分数
分数=分数+3;
//移动字符
charX=charX+1;
//检查游戏是否结束
if(gameOverCollision()){
timer.stop();//结束“延迟循环”
}
//重力
//如果charY不在屏幕下方,以防止数组越界
if(charY<9){
如果(world[charY+1][charX]==0){//向下移动字符/重力
charY=charY+1;
deleter();//删除前面的字符坐标
mover();//移动数组上的字符坐标
}
}
deleter();//删除前面的字符坐标
mover();//移动数组上的字符坐标
}
});
timer.start();//启动“延迟循环”/swing timer
}
public void deleter(){//删除以前的字符坐标,因此屏幕上只有一个字符

对于(int x=0;x 6&&xAt 1&&xAt许多类似问题的类似建议:

  • 在JPanel的
    受保护的void paintComponent
    方法中绘制,而不是在JFrame的绘制方法中绘制。默认情况下,这将提供双缓冲
  • 切勿在绘图方法中读取文件或资源。此方法的速度是感知程序响应的最重要因素,您不应采取任何措施来降低速度。它应仅用于绘图和绘图
  • 相反,将图像读入变量一次,然后从
    paintComponent
    中的变量中绘制图像
  • 将背景图像绘制到BuffereImage,然后在paintComponent方法中绘制

  • 双缓冲区图纸

    在run()方法中,应该有如下内容--

    好的,为了减少fliker--“jump”--你应该应用双缓冲技术。一种方法是让gameRender()绘制到它自己的图形对象中,它将代表与屏幕大小相同的图像

    我的例子是:

    // Global variables for off-screen rendering
    private Graphics dbg;
    private Image dbImage = null;
    
    private void gameRender() {
    /* Draw the current frame to an image buffer*/
        if(dbImage == null) { // create the buffer
            dbImage = createImage(PWIDTH, PHEIGHT);
        if(dbImage == null ) {
            System.out.println("dbImage is null");
            return;
        }
        else
            dbg = dbImage.getGraphics();
        }
        //clear the background
        dbg.setColor(Color.white);
        dbg.fillRect(0, 0, PWIDTH,  PHEIGHT);
    
        // Draws game elements
        // ...
        if(gameOver)
            gameOverMessage(dbg);
    
    } // end gameRender()
    
    作为run()循环中repaint()请求的结果,dbImage被paintComponent()放置在屏幕上--(运行时)…gameUpdate()、Render()、repaint()。。 以下是将dbImage置于屏幕上的调用。此调用是在渲染步骤完成后进行的(上面的代码):

    如果直接在屏幕上进行大范围绘图,则该过程可能需要足够长的时间才能被用户注意到。在paintComponent()中调用drawImage()的速度足够快,因此从一帧到下一帧的变化是即时的

    油漆组件应保持简单

    此外,我还将转换为活动渲染,因为对repaint()的调用只是一个请求,很难知道repaint()何时完成…这意味着动画线程中的睡眠时间(运行时)基本上是一个猜测..当我说睡眠时间时,我的意思是:

    running = true;
    while (running) {
        gameUpdate(); // Game state is updated
        gameRender(); // Render to a buffer
        paintScreen(); // Note: Change from repaint() to paintScreen(),
                       // will explain later.                                      
    try {
      Thread.sleep(20); // sleep a bit.. 20 ms to be exact.
    } catch(InterruptedException ex){}
    } // end of run()
    
    应该有一个指定的睡眠时间,主要原因有三:1.它停止动画线程,从而释放CPU用于其他任务,如垃圾
    public void paintComponent(Graphic g) {
        super.paintComponent(g);
        if (dbImage != null)
        g.drawImage(dbImage, 0,0,null);
    }
    
    running = true;
    while (running) {
        gameUpdate(); // Game state is updated
        gameRender(); // Render to a buffer
        paintScreen(); // Note: Change from repaint() to paintScreen(),
                       // will explain later.                                      
    try {
      Thread.sleep(20); // sleep a bit.. 20 ms to be exact.
    } catch(InterruptedException ex){}
    } // end of run()
    
    running = true;
    while (running) {
        gameUpdate(); // Game state is updated
        gameRender(); // Render to a buffer
        paintScreen(); // Note: Change from repaint() to paintScreen(),
                       // will explain later.                                      
    try {
      Thread.sleep(20); // sleep a bit.. 20 ms to be exact.
    } catch(InterruptedException ex){}
    System.exit(0);
    
     /**
     * Actively render the buffer image to screen
     */
    private void paintScreen() {
        Graphics g;
        try {
            g = this.getGraphics(); // get the panel's graphic context
            if ((g != null) && (dbImage != null))
                g.drawImage(dbImage, 0, 0, null);
            Toolkit.getDefaultToolkit().sync(); // sync the display on some
                                                //  systems
            g.dispose();
        }
        catch (Exception e) {
            System.out.println("Graphics context error: " + e); 
        } // end catch
    } // end paintScreen()
    } // end of run()
    
        private static final int MAX_FRAME_SKIPS = 5;
        // number of frames that can be skipped in any one animation loop
        // i.e the game state is updated but not rendered 
        private static final int NO_DELAYS_PER_YIELD = 16;
        // number of frames with a delay of 0 ms before the animation 
        // thread yields to other running threads.
    
        @Override 
        public void run() {
        /* Repeatedly update, render, sleep so loop takes close
         * to period nsecs. Sleep inaccuracies are handled.
         * The timing calculation use the Java 3D timer.
         * 
         * Overrruns in update/renders will cause extra updates
         * to be carried out so UPS ~== requested FPS 
         */
    
        long beforeTime, afterTime, timeDiff, sleepTime;
        long overSleepTime = 0L; // Number zero of type long (0L)
        int noDelays = 0;
        long excess = 0L;
    
        beforeTime = J3DTimer.getValue();
    
        running = true;
        while (running) {
            gameUpdate(); // Game state is updated
            gameRender(); // Render to a buffer
            paintScreen(); // Draw buffer to screen
    
            afterTime = J3DTimer.getValue();
            timeDiff = afterTime - beforeTime;
            sleepTime = (period - timeDiff) - overSleepTime; // Time left in this
                                                             // loop
    
            if (sleepTime > 0) { // Some time left in this cycle
            try {
                Thread.sleep(sleepTime/1000000L); // nano -> ms
            } catch (InterruptedException ex) {}
                overSleepTime =
                        (J3DTimer.getValue()-afterTime) - sleepTime;
            }
                else { // sleepTime <= 0; frame took longer than the period
                    excess -= sleepTime; // store excess time value
                    overSleepTime = 0L;
    
                    if (++noDelays >= NO_DELAYS_PER_YIELD) {
                        Thread.yield(); // Give another thread a chance to run
                        noDelays = 0; // New thread, no delays.
                } // end inner if
            } // end outer if
            beforeTime = J3DTimer.getValue();
    
            /* If frame animation is taking too long, update the game state
             * without rendering it, to get the updates/sec bearer to required
             * FPS
             * */
            int skips = 0;
            while((excess > period) &&(skips < MAX_FRAME_SKIPS)) {
                excess -= period;
                gameUpdate(); // Update state, but don't render
                skips++;
            }
        } // end while
    
        System.exit(0); // So enclosing JApplet/JFrame exits
    } // end of run()
    
    /**
     * Actively render the buffer image to screen
     */
    private void paintScreen() {
        Graphics g;
        try {
            g = this.getGraphics(); // get the panel's graphic context
            if ((g != null) && (dbImage != null))
                g.drawImage(dbImage, 0, 0, null);
            Toolkit.getDefaultToolkit().sync(); // sync the display on some
                                                // systems
            g.dispose();
        }
        catch (Exception e) {
            System.out.println("Graphics context error: " + e); 
        } // end catch
    } // end paintScreen()