animated background java game

前端 未结 1 821
一生所求
一生所求 2021-01-25 21:39

I was programming a game similar to asteroid, but I do not understand how to spawn the asteroids in the background.

<script

相关标签:
1条回答
  • 2021-01-25 22:12
    1. Don't have your Asteroid class extends JPanel. Instead have it as a class that model's asteroid data and has data manipulation methods. You'll also want to have a draw method that take a Graphic context. Something like

      public class Asteroid {
          Image asteroidImage;
          JPanel panel;
          int x, y;
      
          public Asteroid(JPanel panel, Image image, int x, int y) {
              this.panel = panel;
              this.asteroidImage = image;
              this.x = x;
              this.y = y;
          }
      
          public void drawAsteroid(Graphics g) {
              g.drawImage(asteroidImage, x, y, panel);
          }
      
          public void move() {
              x += 5;
          }
      }
      
    2. Now you have a model of an asteroid, you can create a List of Asteriod objects and iterate through them and use it's drawAsteroid method to paint them. Something like

      public class GamePanel extends JPanel {
          List<Asteroid> asteroids;
          Image asteroidImage;
      
          public GamePanel(){
              asteroidImage = ...
              asteroids = new ArrayList<>();
              asteroids.add(new Asteroid(GamePanel.this, asteroidImage, 100, 100));
              // add more asteriods
          }
      
          @Override
          protected void paintComponent(Graphics g) {
              super.paintComponent(g);
              for (Asteriod asteroid: asteriods) {
                  asteriod.drawAsteroid(g);
              }
          }
      }
      
    3. To animate them, you'll want to use a javax.swing.Timer. See more at How to Use Swing Timers. You'll want to manipulate the Asteriod data in the Timer. With the code provided above, you can just call it's move method, then call repaint(). Something like

      public GamePanel(){
          ...
          Timer timer = new Timer(30, new ActionListener(){
              public void actionPerformed(ActionEvent e) {
                  Iterator it = asteroids.iterator();
                  while (it.hasNaext()) {
                      Asteroid asteriod = (Asteroid)it.next();
                      asteroid.move();
                  }
              }
          });
      }
      

    You can see a bunch more complete example of animating multiple objects here and here and here and here and here


    Here's a full example. You'll see I included a Rectangle2D object in the Astreroid class. That's just if you want to check for collision detection. You should move the Rectangle2D x and/or y with every Asreroid movement of x and y. Then you can check if asteroid.rectangle.intersects(someOtherObject)

    enter image description here

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Rectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Random;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class AsteroidBackground extends JPanel {
    
        private static final int D_W = 400;
        private static final int D_H = 600;
        BufferedImage asteroidImage;
        BufferedImage background;
        List<Asteroid> asteroids;
        Random random = new Random();
        int countToAddAsteroid = 0;
        int y;
    
        public AsteroidBackground() {
            try {
                asteroidImage = ImageIO.read(getClass().getResource("/resources/small-asteroid.png"));
                background = ImageIO.read(getClass().getResource("/resources/space.png"));
            } catch (IOException ex) {
                Logger.getLogger(AsteroidBackground.class.getName()).log(Level.SEVERE, null, ex);
            }
            asteroids = new ArrayList<>();
            y = 0 - asteroidImage.getHeight();
    
            Timer timer = new Timer(40, new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    if (countToAddAsteroid >= 25) {
                        int randX = random.nextInt(D_W);
                        asteroids.add(new Asteroid(AsteroidBackground.this, asteroidImage, randX, y));
                        countToAddAsteroid = 0;
                    }
                    countToAddAsteroid++;
                    Iterator it = asteroids.iterator();
                    while (it.hasNext()) {
                        Asteroid asteroid = (Asteroid)it.next();
                        if (asteroid.y >= D_H) {
                            it.remove();
                        } else {
                             asteroid.move();
                        } 
                    }
                    repaint();
                }
            });
            timer.start();
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(background, 0, 0, this);
            for (Asteroid asteroid : asteroids) {
                asteroid.drawAsteroid(g);
            }
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(D_W, D_H);
        }
    
        public class Asteroid {
            Rectangle2D rectangle;
            Image asteroidImage;
            JPanel panel;
            int x, y;
    
            public Asteroid(JPanel panel, Image image, int x, int y) {
                this.panel = panel;
                this.asteroidImage = image;
                this.x = x;
                this.y = y;
                rectangle = new Rectangle2D.Double(
                        x, y, image.getWidth(panel), image.getHeight(panel));
            }
    
            public void drawAsteroid(Graphics g) {
                g.drawImage(asteroidImage, x, y, panel);
            }
    
            public void move() {
                y += 5;
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new AsteroidBackground());
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题