Java графика замедляется после добавления объектов - PullRequest
1 голос
/ 26 мая 2020

Я все еще новичок в java, и я пытался сделать копию SpaceInvaders в нативной графике Java. Я закончил базовую c механику, однако игра значительно замедляется, когда игрок или инопланетяне стреляют пулей. Я попытался выяснить, из-за чего игра замедляется, но не смог.

public class Board extends JPanel implements KeyListener,ActionListener{

    Ship ship;
    Alien[] row1 = new Alien[10];
    Alien[] row2 = new Alien[10];
    Alien[] row3 = new Alien[10];
    private Timer timer;
    int DELAY = 16;
    boolean reachedend = false;
    Bullet bullet;
    int lives;


    public Board() {
        setBackground(Color.BLACK);
        addKeyListener(this);

        lives = 3;
        ship = new Ship();
        fillAliens();

        timer = new Timer(DELAY, this);
        timer.start();
    }

    void fillAliens() {
        for(int x=1;x<11;x++) {
            row1[x-1] = new Alien(x*30+40,30);
            row2[x-1] = new Alien(x*30+40,70);
            row3[x-1] = new Alien(x*30+40,110);
        }
    }

    void shoot() {
        if(bullet==null) {
        bullet = new Bullet(ship.x + ship.width/2,ship.y - ship.height/2,-1);
        }

    }

    void drawAliens(Graphics2D g) {
        g.setColor(Color.red);

        for(int x=1;x<11;x++) {
            if(row1[x-1].alive == true) {
                g.fillRect(row1[x-1].x_loc, row1[x-1].y_loc, row1[x-1].width, row1[x-1].width);
            }
            if(row2[x-1].alive == true) {
                g.fillRect(row2[x-1].x_loc, row2[x-1].y_loc, row2[x-1].width, row2[x-1].width);
            }
            if(row3[x-1].alive == true) {
                g.fillRect(row3[x-1].x_loc, row3[x-1].y_loc, row3[x-1].width, row2[x-1].width);
            }
        }
    }

    public void addNotify() {
        super.addNotify();
        requestFocus();
    }

    void drawShip(Graphics2D g) {

        g.fillRect(ship.x, ship.y, ship.width, ship.height);

    }

    @Override
    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();
      if(lives>0) {  
        if (key == KeyEvent.VK_SPACE) {
            shoot();
        }

        if (key == KeyEvent.VK_LEFT) {
            if(ship.x>=5) {
                ship.x -= 5;

            }
        }

        if (key == KeyEvent.VK_RIGHT) {
            if(ship.x+ship.width<434) {
                ship.x += 5;
            }
        }
      }
        repaint();   
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        drawShip(g2);
        drawAliens(g2);
        drawBullet(g2); 
        drawAlienBullet(g2);
        drawLives(g2);
    }

    private void drawLives(Graphics2D g2) {
        g2.setColor(Color.white);

        g2.drawString("Lives:", 10, 300);

        for(int x=1; x<=lives;x++) {
            g2.fillRect(15*x+30, 290, 10, 10);
        }
    }

    private void drawBullet(Graphics2D g2) {
        g2.setColor(Color.GREEN);
        if(bullet!=null) {
            g2.fillRect(bullet.x_loc, bullet.y_loc, bullet.width, bullet.height);
        }
    }
    private void drawAlienBullet(Graphics2D g2) {
        g2.setColor(Color.BLUE);

        for(int x=0;x<10;x++) {
            if(row3[x].bullet != null) {
                g2.fillRect(row3[x].bullet.x_loc, row3[x].bullet.y_loc, row3[x].bullet.width, row3[x].bullet.height);
            }
            if(row2[x].bullet != null) {
                g2.fillRect(row2[x].bullet.x_loc, row2[x].bullet.y_loc, row2[x].bullet.width, row2[x].bullet.height);

            }
            if(row1[x].bullet != null ) {
                g2.fillRect(row1[x].bullet.x_loc, row1[x].bullet.y_loc, row1[x].bullet.width, row1[x].bullet.height);

            }
        }

    }

    private void bulletHitPlayer() {
        for(int x=0;x<10;x++) {
            if(row3[x].bullet != null) {
                if(row3[x].bullet.y_loc >= 350) {
                    row3[x].bullet = null;
                    break;
                }
            }
            if(row2[x].bullet != null) {
                if(row2[x].bullet.y_loc >= 350) {
                    row2[x].bullet = null;
                    break;
                }
            }
            if(row1[x].bullet != null) {
                if(row1[x].bullet.y_loc >= 350) {
                    row1[x].bullet = null;
                    break;
                }
            }

            if(row3[x].bullet != null && row3[x].bullet.y_loc + 10 >= ship.y && row3[x].bullet.y_loc <= ship.y + ship.height && row3[x].bullet.x_loc >= ship.x && row3[x].bullet.x_loc <= ship.x+ship.width) {
                row3[x].bullet = null;
                lives--;
                break;
            }
            if(row2[x].bullet != null && row2[x].bullet.y_loc + 10 >= ship.y && row2[x].bullet.y_loc <= ship.y + ship.height && row2[x].bullet.x_loc >= ship.x && row2[x].bullet.x_loc <= ship.x+ship.width) {
                row2[x].bullet = null;
                lives--;
                break;
            }
            if(row1[x].bullet != null && row1[x].bullet.y_loc + 10 >= ship.y && row1[x].bullet.y_loc <= ship.y + ship.height && row1[x].bullet.x_loc >= ship.x && row1[x].bullet.x_loc <= ship.x+ship.width) {
                row1[x].bullet = null;
                lives--;
                break;
            }

        }


    }

    private void bulletHit() {
        if(bullet!=null) {
        for(int x=0;x<10;x++) {
            if(row3[x].alive == true && bullet.y_loc >= row3[x].y_loc && bullet.y_loc <= row3[x].y_loc+row3[x].width && bullet.x_loc >= row3[x].x_loc && bullet.x_loc <= row3[x].x_loc+row3[x].width) {
                row3[x].alive = false;
                bullet=null;
                break;
            }
            if(row2[x].alive == true && bullet.y_loc >= row2[x].y_loc && bullet.y_loc <= row2[x].y_loc+row2[x].width && bullet.x_loc >= row2[x].x_loc && bullet.x_loc <= row2[x].x_loc+row2[x].width) {
                row2[x].alive = false;
                bullet=null;
                break;
            }
            if(row1[x].alive == true && bullet.y_loc >= row1[x].y_loc && bullet.y_loc <= row1[x].y_loc+row1[x].width && bullet.x_loc >= row1[x].x_loc && bullet.x_loc <= row1[x].x_loc+row1[x].width) {
                row1[x].alive = false;
                bullet=null;
                break;
            }
        }
        }
        if(bullet!=null) {
            if(bullet.y_loc<0) {
                bullet=null;
            }
        }

    }

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyReleased(KeyEvent e) {}

    @Override
    public void actionPerformed(ActionEvent e) {

        bulletHitPlayer();
        bulletHit();
        repaint();
    }
}

1 Ответ

0 голосов
/ 16 июня 2020

Проблема:

Вы рисуете свою сцену всякий раз, когда нажимаете клавишу; и вы рисуете свою сцену один раз при запуске (см. API и Учебники ) - Но вы должны постоянно перерисовывать свою сцену, правильно используя Timer.

Как решить:

При создании Timer пусть он

  • либо повторяется timer.setRepeats(true);
  • , либо перезапускает Timer вручную:
public void actionPerformed(ActionEvent e) {
    bulletHitPlayer();
    bulletHit();
    repaint();
    timer.restart(); //manually restart the timer
}
...