Java 如何重复绘制图像?

Java 如何重复绘制图像?,java,Java,我正在尝试用JavaSwing制作简单的汽车游戏。我想要背景移动。当背景图像向下移动时,我必须再次连续地绘制它。 我该怎么做? 注:背景和背景是同一张图片 package com.mycompany.cardemo.car; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.sw

我正在尝试用JavaSwing制作简单的汽车游戏。我想要背景移动。当背景图像向下移动时,我必须再次连续地绘制它。 我该怎么做? 注:背景和背景是同一张图片

package com.mycompany.cardemo.car;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
*
* @author Suraj Gautam
*/
public class MainScreen extends JPanel implements ActionListener {



  Timer timer = new Timer(20, this);
  private ImageIcon background = new ImageIcon(getClass().getResource("/res/background.png"));
  private ImageIcon background2 = new ImageIcon(getClass().getResource("/res/background1.png"));
  private int x = 0;
  private int y = 0;
  private int velX = 1;
  private int velY = 1;

  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    background.paintIcon(this, g, x, y);
    if (y > 0 && y<400) {
        background2.paintIcon(this, g, x, y);
    }


    timer.start();

  }

  public static void main(String[] args) {
    JFrame f = new JFrame("Car game");
    f.setSize(400, 400);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(new MainScreen());
    f.setResizable(true);
    f.setVisible(true);

  }

  @Override
  public void actionPerformed(ActionEvent e) {

    y += velY;
    repaint();

  }

  public void updateValueOfy(int y) {
    this.y = y;
  }
}
package com.mycompany.cardemo.car;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.Timer;
/**
*
*@作者Suraj Gautam
*/
公共类MainScreen扩展JPanel实现ActionListener{
定时器=新定时器(20,此);
私有ImageIcon background=新的ImageIcon(getClass().getResource(“/res/background.png”);
private ImageIcon background2=新的ImageIcon(getClass().getResource(“/res/background1.png”);
私有整数x=0;
私有整数y=0;
私有int velX=1;
私有int=1;
@凌驾
公共组件(图形g){
超级组件(g);
背景。画图图标(这个,g,x,y);

如果(y>0&&y在程序中
background.paintIcon(this,g,x,y);
background2.paintIcon(this,g,x,y);
将在图像1的顶部绘制图像2,因为它们具有相同的原点(x,y)

您需要做的至少是
background2.paintIcon(这个,g,x,y+background.getIconHeight());
这样图像1和图像2就不会重叠

此外,为了实现最终目标,需要使用Y作为绘制的锚定点,要在整个帧上重复绘制两个图像,可以使用以下方法

  • 从Y向下交替绘制图像1和图像2,直到到达帧的末端
  • 从Y-(图像2的高度)向上交替绘制图像2和图像1,直到到达帧的起点
  • 一旦Y到达帧的末尾,它需要从帧的开头重新开始
  • 重新启动Y时,需要考虑image1和image2的高度,以防止出现故障
  • 下面是一个示例列表,该列表已在我的计算机上证明有效:

    private int bg1Height = background.getIconHeight();
    private int bg2Height = background2.getIconHeight();
    // painting height should be a multiple of (bg1height + bg2height) that is immediately larger than frameHeight
    private int paintingHeight = ((frameHeight / (bg1Height + bg2Height)) + 1)  * (bg1Height + bg2Height);
    
    public static int frameHeight = 400;
    
    public MainScreen() {
        timer.start();
    }
    
    public void actionPerformed(ActionEvent e) {
        y = (y + velY) % paintingHeight;
        repaint();
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
        // paint downwards repeatedly
        int yTemp = y;
        while (yTemp < 400) {
            background.paintIcon(this, g, x, yTemp);
            yTemp += bg1Height;
            if (yTemp < 400) {
                background2.paintIcon(this, g, x, yTemp);
                yTemp += bg2Height;
            }
        }
    
        // paint upwards repeatedly
        yTemp = y;
        while (yTemp > 0) {
            yTemp -= bg2Height;
            background2.paintIcon(this, g, x, yTemp);
            if (yTemp > 0) {
                yTemp -= bg1Height;
                background.paintIcon(this, g, x, yTemp);
            }
        }
    }
    
    private int bg1Height=background.getIconHeight();
    private int bg2Height=background2.getIconHeight();
    //绘制高度应为(bg1height+bg2height)的倍数,该倍数应立即大于frameHeight
    私人内部喷漆高度=((框架高度/(bg1Height+bg2Height))+1)*(bg1Height+bg2Height);
    公共静态int frameHeight=400;
    公共主屏幕(){
    timer.start();
    }
    已执行的公共无效操作(操作事件e){
    y=(y+y)%油漆高度;
    重新油漆();
    }
    @凌驾
    公共组件(图形g){
    超级组件(g);
    //反复向下涂刷
    int yTemp=y;
    而(yTemp<400){
    背景.paintIcon(this,g,x,yTemp);
    yTemp+=BG1高度;
    如果(yTemp<400){
    背景2.画图图标(这个,g,x,yTemp);
    yTemp+=BG2高度;
    }
    }
    //反复往上涂
    yTemp=y;
    而(yTemp>0){
    yTemp-=bG2高度;
    背景2.画图图标(这个,g,x,yTemp);
    如果(yTemp>0){
    yTemp-=BG1高度;
    背景.paintIcon(this,g,x,yTemp);
    }
    }
    }
    
    如果您想从位置
    (0,0)
    重复绘制图像,只需重置
    x和y
    坐标,如下所示: 假设
    JFrame
    的最大高度为400

      @Override
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
        if(y >= 400) {
            y = 0;  x = 0;
        }
    
        background.paintIcon(this, g, x, y);
        timer.start();
    
      }
    

    我试过你的程序,background2.paintIcon对我有效。需要注意的是,你的帧大小是400 x 400,绘制background2的条件是y>0和y<400。因此,在你的帧的整个可视区域中,背景2都会被绘制。将背景1和背景2精确地放在这里,你想实现什么?I d在上,我不希望该帧为空。我希望图像重复移动。每当背景图像移动时,我希望立即绘制下一个图像,使帧看起来不为空。图像根本不移动?我将timer.start()移动到主屏幕的构造函数中,因为定时器只需启动一次。可能您错过了该部分?