animated background java game

孤者浪人 提交于 2019-12-31 07:16:12

问题


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

now i spawn an asteroid in the main class but i want create a class for the asteroid ho i do it?

MAIN CLASS

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    if(flag_img)
    {
        background(g2d);  
        logo(g2d);          
        menu(g2d);          
        spaceship(g2d);   
        crediti(g2d);    
    }
}

background function(now)

private void background(Graphics2D g2d) 
{

    asteroidi_g_x+=r.nextInt(4);
    asteroidi_g_y+=r.nextInt(1);
    g2d.drawImage(asteroidi_g[0], asteroidi_g_x,asteroidi_g_y,this);
}

background function(what i want)

private void background(Graphics2D g2d) 
{
    asteroid asteroid = new asteroid[10];
}

and class asteroid

public class asteroid extends JPanel implements ActionListener
{
   private BufferedImage images_asteroid;
   private boolean flag_img;

   private JPanel jp;

   private int x,y;

   public asteroide_grande(JPanel jp)
   {
    flag_img = true;
    x = (jp.getWidth()/2);
    y = (jp.getHeight()/2);
    this.jp = jp;

        try {
            images_asterod = ImageIO.read(this.getClass().getResource("images/asteroid/a1.png"));
        } catch(IOException e){flag = false;}
}

@Override
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
   if(flag_img)
  {
        g.drawImage(images_asteroid, 100, 100,this);
  }
}


@Override
public void actionPerformed(ActionEvent e) 
{
    x=x-1;
    y=y+1;
    repaint();
}

method paintcomponent in class doesn't work


回答1:


  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)

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);
            }
        });
    }
}


来源:https://stackoverflow.com/questions/22592180/animated-background-java-game

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!