【问题标题】:animated background java game动画背景java游戏
【发布时间】:2014-04-30 19:02:06
【问题描述】:

我正在编写一个类似于小行星的游戏,但我不明白如何在后台生成小行星。

现在我在主类中生成了一个小行星,但我想为小行星创建一个类,我这样做了吗?

主类

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

后台功能(现在)

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

后台功能(我想要的)

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

和类小行星

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

类中的方法paintcomponent不起作用

【问题讨论】:

  • 您只想移动图像中的那一个小行星?就这样?
  • 我想生成一个小行星数组 (10),当我实例化一个小行星时,类构造函数会生成一个随机坐标并且小行星在 jpanel 中移动
  • 请参阅下面的完整示例。
  • 我没有使用数组,而是使用了List,当我在计时器中循环遍历它时,如果小行星不在屏幕上,我将其从列表中删除。我还每秒添加一个新的小行星作为随机 x 位置

标签: java swing animation graphics 2d-games


【解决方案1】:
  1. 不要让您的 Asteroid 类扩展 JPanel。而是将其作为类来模拟小行星数据并具有数据操作方法。您还需要一个采用Graphic 上下文的draw 方法。类似的东西

    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. 现在你有一个小行星的模型,你可以创建一个ListAsteriod 对象并遍历它们并使用它的drawAsteroid 方法来绘制它们。类似的东西

    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. 要为它们设置动画,您需要使用javax.swing.Timer。在How to Use Swing Timers 上查看更多信息。您需要操作Timer 中的Asteriod 数据。使用上面提供的代码,您可以调用它的move 方法,然后调用repaint()。像

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

你可以看到一个更完整的动画多个对象的例子hereherehereherehere


这是一个完整的例子。你会看到我在Astreroid 类中包含了一个Rectangle2D 对象。那只是如果您想检查碰撞检测。您应该移动Rectangle2D x 和/或yxy 的每个Asreroid 移动。然后你可以检查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);
            }
        });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多