Как удвоить буфер прямоугольников

1

Он всегда работает с изображениями, но прямоугольники и овалы никогда не запираются правильно. У меня есть базовый игровой цикл в моем классе игровой панели, который многократно рисует игрока. Он не удаляет прямоугольник, просто оставляет след. Я хочу использовать прямоугольник вместо изображения для целей обучения. Я попытался использовать перерисовку в игровом цикле, но он мерцал, как сумасшедший, и все еще не работал. Я посмотрел на другой учебник по этому вопросу на этом веб-сайте, но они использовали opengl witch для меня чуждо, и я не хочу тратить время на это.

JFrame:

import javax.swing.JFrame;

public class Game {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setTitle("OMG I MADE A GAME");
        f.setResizable(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(new Panel());
        f.pack();

        f.setVisible(true);
       }
   }

Класс JPanel:

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.JPanel;
import com.game.entity.Player;

public class Panel extends JPanel implements Runnable, KeyListener{ 

private static final long serialVersionUID = -5122190028751177848L;
    // dimensions
    public static final int WIDTH = 320;
    public static final int HEIGHT = 240;
    public static final int SCALE = 2;      
    // game thread
    private Thread thread;
    private boolean running;        
    // image
    private BufferedImage image;
    private Graphics2D g;

    private Player p;

    public Panel() {
        super();
        setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        setFocusable(true);
        requestFocus();
    }
    // DRAWS PANEL TO FRAME
    public void addNotify() {
        super.addNotify();
        if(thread == null) {
            thread = new Thread(this);
            addKeyListener(this);
            thread.start();
        }
    }

    private void init() {           
        image = new BufferedImage(
                    WIDTH, HEIGHT,
                    BufferedImage.TYPE_INT_RGB                  );
        g = (Graphics2D) image.getGraphics();
        p = new Player(100, 100);           
        running = true;
    }

    public void run() {         
        init();
        // game loop
        while(running) {                
            update();
            draw();
            drawToScreen();  
            System.out.println("ELAPSED :" + System.nanoTime()/ 1000000 + " Seconds");              
            try {
                Thread.sleep(10);
            }
            catch(Exception e) {
                e.printStackTrace();
            }           
        }           
    }

    private void update() {
        p.update();
    }
    private void draw(){
        // NAME (remember it loops) 
        String name = "2014 Jay H.";
        g.setFont(new Font("Name", 0, 12)); 
        g.setColor(Color.WHITE);
        g.drawString(name, 0, 10);
        g.setColor(Color.BLUE);
        g.fillRect( 0, 10, 65, 5);          
        //TITLE                       looks sexy :D
        g.setColor(Color.GREEN);
        g.setFont(new Font("Title", 0, WIDTH/ 10));
        g.drawString("JAY'S GAME", WIDTH/ 5, 100);
        //DRAW PLAYER
        p.draw(g);

        }
    // SCREEN IMAGE (dont have to use. Just use this^)
    private void drawToScreen() {  
        Graphics g2 = getGraphics();
        g2.drawImage(image, 0, 0,
                WIDTH * SCALE, HEIGHT * SCALE,null);
        g2.dispose(); 
    }

    public void keyTyped(KeyEvent key) {}

    // PUBLIC KEYRELEASES
    public void keyPressed(KeyEvent key) {
        int KeyCode = key.getKeyCode();             
        //EXIT SYSTEM
        if(KeyCode == KeyEvent.VK_Q) {System.exit(0);
            }           //UP
        if(KeyCode == KeyEvent.VK_W){p.setDY(-2);}      
    }       

    // PUBLIC KEYRELEASES
    public void keyReleased(KeyEvent key) {
        int KeyCode = key.getKeyCode();             
        //UP
        if(KeyCode == KeyEvent.VK_W) {p.setDY(0);}
    }      
}

Класс игрока:

   import java.awt.Color;
   import java.awt.Graphics2D;
   import java.awt.Image;      
   import javax.swing.ImageIcon;

    //FOR NOW THE PLAYER IS A RECTANGLE
   public class Player {

    // PLAYER CORDINATES AND VELOCITY
    int x,y,dx,dy;      

    public Player(int x, int y) {           
        //NEEDED TO USE THE X AND Y
        this.x =x;
        this.y = y;
    } 

    public void update() {
        x += dx;
        y += dy;            
    }

    // DRAW TO PANEL CLASS
    public void draw(Graphics2D g) {
        //BODY
        g.setColor(Color.PINK);
        g.fillRect(x, y, 20, 20);
        //EYES
        g.setColor(Color.BLACK);
        g.fillRect(x+3, y+2, 5, 10);
        g.fillRect(x+ 12, y+2, 5, 10);
        //EYERIS
        g.setColor(Color.WHITE);
        g.fillRect(x+3, y+2, 2, 10);
        g.fillRect(x+15, y+2, 2, 10);
        //NOSE
        g.setColor(Color.MAGENTA);
        g.fillRect(x+5, y+13, 10, 5);
        //NOSTRILLS
        g.setColor(Color.red);
        g.fillRect(x+6, y+15, 2, 2);
        g.fillRect(x+12, y+15, 2, 2);           
    }

    //GET METHODS FOR CORDINATES AND VELOCITY  (Unused for now... i think)
    public int getX() {return x;}
    public int getY() {return y;}
    public int getDX() {return dx;}
    public int getDY() {return dy;}         
    //SET METHODS TO CHANGE
    public void setX(int x) {this.x = x;}
    public void setY(int y) {this.y = y;}
    public void setDX(int dx) {this.dx = dx;}
    public void setDY(int dy) {this.dy = dy;}
 }
Теги:
swing
jpanel
keylistener
thread-sleep

1 ответ

0

Вам необходимо "сбросить" фон буфера, прежде чем рисовать его.

Помните, что живопись является накапливающейся, то есть, что вы когда-либо писали ранее, останется. Вам нужно будет перестраивать каждый кадр с нуля каждый раз, когда вы рисуете его

Мерцание произойдет по двум причинам...

  1. Вы используете компоненты на основе AWT, которые не являются двойными буферными
  2. Вы являетесь основной paint контейнера верхнего уровня, такого как JFrame, который не является двойной буферизацией.

Вы должны либо использовать BufferStrategy либо переопределить метод paintComponent компонента Swing, например JPanel который по умолчанию используется по умолчанию

  • 0
    Я добавил код

Ещё вопросы

Сообщество Overcoder
Наверх
Меню