Java 在背景图像上设置动画
我已经创建了一个窗口,其中有一个大的JPanel,占据了该区域的大部分,将用于设置一组焰火的动画。我有一个私有的内部类AnimationPanel,它扩展了JPanel。为了使用缓冲图像作为背景,我重写了paintComponent()。按下“开始”按钮后,将运行模拟,该模拟将设置焰火的动画。现在,此模拟将位置输出到控制台,并生成一个名为快照的集合,其中包含特定时间点的所有焰火 目前,我已经成功地绘制了背景和一个小矩形来表示发射管,但是当我试图从快照中绘制焰火时,什么也没有显示。在这一点上,我并不关心动画(仍在学习如何使用Timer类来实现这一点),但我需要知道绘制将起作用,所以我只是尝试绘制快照。在得到快照后,我将在模拟结束时重新绘制animationPanel 私有内部类AnimationPanelJava 在背景图像上设置动画,java,swing,graphics,jpanel,drawing,Java,Swing,Graphics,Jpanel,Drawing,我已经创建了一个窗口,其中有一个大的JPanel,占据了该区域的大部分,将用于设置一组焰火的动画。我有一个私有的内部类AnimationPanel,它扩展了JPanel。为了使用缓冲图像作为背景,我重写了paintComponent()。按下“开始”按钮后,将运行模拟,该模拟将设置焰火的动画。现在,此模拟将位置输出到控制台,并生成一个名为快照的集合,其中包含特定时间点的所有焰火 目前,我已经成功地绘制了背景和一个小矩形来表示发射管,但是当我试图从快照中绘制焰火时,什么也没有显示。在这一点上,我并
private class AnimationPanel extends JPanel {
private BufferedImage background;
public AnimationPanel() {
super();
try {
background = ImageIO.read(new File("background.jpg"));
} catch(IOException error) {
error.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background,0,0,getWidth(),getHeight(),this); //this shows up
g.setColor(Color.RED);
g.fillRect(getWidth()/2, getHeight()-30, 10, 30); //this shows up
paintFireWorks(g); //this doesn't show up
}
private void paintFireWorks(Graphics g) {
if(snapshot != null) {
for(Firework item: snapshot) {
double[] position = item.getPosition();
if(item instanceof Star){
int x = (int)Math.round(position[0])+animationPanel.getWidth()/2;
int y = animationPanel.getHeight()-(int)Math.round(position[1]);
int r = ((Star) item).getRenderSize();
g.fillOval(x,y,r,r);
} else if(item instanceof Spark){
int x1 = (int)Math.round(position[0])+animationPanel.getWidth()/2;
int x2 = (int)Math.round(position[0])-((Spark)item).getRenderSize();
int y1 = animationPanel.getHeight()-(int)Math.round(position[1]);
int y2 = animationPanel.getHeight()-(int)Math.round(position[1])+((Spark)item).getRenderSize();
g.drawLine(x1,y1,x2,y2);
}
}
}
}
}
整个FireWorksWindow类:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class FireWorksWindow extends JFrame {
//DIMENSIONS AND POSITIONS
private final int STARTING_POS_X = 1600;
private final int STARTING_POS_Y = 100;
//CONTAINERS AND COMPONENTS
private AnimationPanel animationPanel;
private JPanel controlPanel, sliderPanel;
private Box controlBox;
private JLabel windSliderLabel, angleSliderLabel;
private JSlider windSpeed, launchAngle;
private JButton startButton, pauseButton, exitButton;
//TIMER
private Timer animationTimer;
//COLLECTIONS
ArrayList<Particle> fireworks;
ArrayList<Particle> snapshot;
//CONSTRUCTOR
public FireWorksWindow() {
setTitle("Roman Candle Animation");
setLocation(STARTING_POS_X,STARTING_POS_Y);
setDefaultCloseOperation(EXIT_ON_CLOSE);
sliderPanel = new JPanel();
GridBagLayout sliderGrid = new GridBagLayout();
sliderPanel.setLayout(sliderGrid);
initSliders();
initLabels();
addComponent(sliderGrid, windSliderLabel, 1,1,new Insets(5,10,5,10));
addComponent(sliderGrid, angleSliderLabel, 1,2,new Insets(5,10,5,10));
addComponent(sliderGrid, windSpeed, 2,1,new Insets(5,10,5,10));
addComponent(sliderGrid, launchAngle, 2,2,new Insets(5,10,5,10));
controlPanel = new JPanel();
controlPanel.setLayout(new BoxLayout(controlPanel,BoxLayout.X_AXIS));
initButtons();
initControlBox();
controlPanel.add(controlBox);
controlPanel.setBorder(BorderFactory.createLineBorder(Color.MAGENTA , 3 ));
animationPanel = new AnimationPanel();
animationPanel.setSize(new Dimension(750,500));
animationPanel.setMinimumSize(new Dimension(animationPanel.getWidth(),animationPanel.getHeight()));
animationPanel.setPreferredSize(new Dimension(animationPanel.getWidth(),animationPanel.getHeight()));
add(animationPanel,BorderLayout.CENTER);
add(controlPanel,BorderLayout.SOUTH);
pack();
setMinimumSize(new Dimension(getWidth(),getHeight()));
sliderPanel.setMaximumSize(new Dimension(sliderPanel.getWidth(), sliderPanel.getHeight()));
}
//CONVENIENCE METHODS
private void addComponent(GridBagLayout layout, Component component, int row, int column, Insets padding) {
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = column;
constraints.gridy = row;
constraints.insets = padding;
layout.setConstraints(component, constraints);
sliderPanel.add(component);
}
private void initLabels() {
windSliderLabel = new JLabel("Wind Speed");
angleSliderLabel = new JLabel("Launch Angle");
}
private void initSliders() {
windSpeed = new JSlider(-20,20);
windSpeed.setMajorTickSpacing(10);
windSpeed.setMinorTickSpacing(5);
windSpeed.setPaintTicks(true);
windSpeed.setPaintLabels(true);
launchAngle = new JSlider(-15,15);
launchAngle.setMajorTickSpacing(5);
launchAngle.setMinorTickSpacing(1);
launchAngle.setPaintTicks(true);
launchAngle.setPaintLabels(true);
}
private void initButtons() {
startButton = new JButton("Start");
startButton.addActionListener(new StartHandler());
pauseButton = new JButton("Pause");
pauseButton.addActionListener(new PauseHandler());
exitButton = new JButton("Exit" );
exitButton.addActionListener(new ExitHandler());
}
private void initControlBox() {
controlBox = Box.createHorizontalBox();
controlBox.add(Box.createHorizontalStrut(10));
controlBox.add(sliderPanel);
controlBox.add(Box.createHorizontalStrut(30));
controlBox.add(startButton);
controlBox.add(Box.createHorizontalStrut(10));
controlBox.add(pauseButton);
controlBox.add(Box.createHorizontalGlue());
controlBox.add(Box.createHorizontalStrut(10));
controlBox.add(Box.createHorizontalGlue());
controlBox.add(exitButton);
controlBox.add(Box.createHorizontalStrut(10));
}
//ACTION LISTENERS
public class WindAdjustListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
}
}
public class AngleAdjustListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
}
}
public class StartHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("START Pressed");
startButton.setText("Reset");
repaint();
runAnimation();
startButton.setText("Start");
}
}
public class PauseHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("PAUSE Pressed");
}
}
public class ExitHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
if(animationTimer != null)
if(animationTimer.isRunning())
animationTimer.stop();
System.exit(0);
}
}
public class AnimationClock implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
}
}
//ACCESSORS
public double[] getSliderValues() {
double[] sliders = new double[2];
sliders[0] = windSpeed.getValue();
sliders[1] = launchAngle.getValue();
return sliders;
}
//OTHER METHODS
public void runAnimation() {
double[] inputs = getSliderValues();
double wind = inputs[0];
double launchAngle = inputs[1];
double timeInterval = 0.05; // seconds
ParticleManager manager = null;
try {
manager = new ParticleManager(wind, launchAngle);
} catch (EnvironmentException except) {
System.out.println(except.getMessage());
return;
} catch (EmitterException except) {
System.out.println(except.getMessage());
return;
}
System.out.println("Counts:");
System.out.println("time\tStars\tSparks\tLaunchSparks");
double time = 0;
manager.start(time);
fireworks = manager.getFireworks(time);
do {
//if (time % 0.5 == 0)
showTypesCount(fireworks, time);
if (Math.abs(time - 2.0) < timeInterval)
snapshot = fireworks;
time += timeInterval;
fireworks = manager.getFireworks(time);
} while (fireworks.size() > 0);
showFireworks(snapshot, 2.0);
animationPanel.repaint();
}
public void showFireworks(ArrayList<Particle> fireworks, double time) {
if (fireworks == null)
return;
System.out.printf("\nAt time%5.2f seconds:\n", time);
System.out.println("Type\t\tPosition (metres)");
for (Particle firework : fireworks)
System.out.println(firework);
}
public void showTypesCount(ArrayList<Particle> fireworks, double time) {
int starCount = 0;
int sparkCount = 0;
int launchSparkCount = 0;
for (Particle firework : fireworks) {
if (firework instanceof Star)
starCount++;
else if (firework instanceof LaunchSpark)
launchSparkCount++;
else
sparkCount++;
}
System.out.printf("%5.2f\t", time);
System.out.println(starCount + "\t" + sparkCount + "\t" + launchSparkCount);
}
private class AnimationPanel extends JPanel {
private BufferedImage background;
public AnimationPanel() {
super();
try {
background = ImageIO.read(new File("background.jpg"));
} catch(IOException error) {
error.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background,0,0,getWidth(),getHeight(),this); //this shows up
g.setColor(Color.RED);
g.fillRect(getWidth()/2, getHeight()-30, 10, 30); //this shows up
paintFireWorks(g); //this doesn't show up
}
private void paintFireWorks(Graphics g) {
if(snapshot != null) {
for(Firework item: snapshot) {
double[] position = item.getPosition();
if(item instanceof Star){
int x = (int)Math.round(position[0])+animationPanel.getWidth()/2;
int y = animationPanel.getHeight()-(int)Math.round(position[1]);
int r = ((Star) item).getRenderSize();
g.fillOval(x,y,r,r);
} else if(item instanceof Spark){
int x1 = (int)Math.round(position[0])+animationPanel.getWidth()/2;
int x2 = (int)Math.round(position[0])-((Spark)item).getRenderSize();
int y1 = animationPanel.getHeight()-(int)Math.round(position[1]);
int y2 = animationPanel.getHeight()-(int)Math.round(position[1])+((Spark)item).getRenderSize();
g.drawLine(x1,y1,x2,y2);
}
}
}
}
}
import java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.ArrayList;
导入javax.imageio.imageio;
导入javax.swing.*;
@抑制警告(“串行”)
公共类FireWorksWindow扩展了JFrame{
//尺寸和位置
私人最终整数起始位置X=1600;
私人最终整数起始位置Y=100;
//容器和组件
私有动画面板动画面板;
专用JPanel控制面板,滑动面板;
专用控制箱;
私人JLabel windSliderLabel、angleSliderLabel;
私人JSlider风速、发射角;
私有JButton开始按钮、暂停按钮、退出按钮;
//计时器
私人定时器动画定时器;
//收藏
ArrayList烟花;
阵列列表快照;
//建造师
公共消防设施{
片名(“罗马蜡烛动画”);
设置位置(起始位置X、起始位置Y);
setDefaultCloseOperation(关闭时退出);
sliderPanel=新的JPanel();
GridBagLayout sliderGrid=新建GridBagLayout();
sliderPanel.setLayout(sliderGrid);
初始化滑块();
initLabels();
addComponent(sliderGrid,windSliderLabel,1,1,新插图(5,10,5,10));
addComponent(sliderGrid,angleSliderLabel,1,2,新插图(5,10,5,10));
添加组件(sliderGrid,风速,2,1,新插图(5,10,5,10));
addComponent(sliderGrid,launchAngle,2,2,新插图(5,10,5,10));
控制面板=新的JPanel();
控制面板.setLayout(新的BoxLayout(控制面板,BoxLayout.X_轴));
初始化按钮();
initControlBox();
控制面板。添加(控制盒);
controlPanel.setBorder(BorderFactory.createLineBorder(Color.MAGENTA,3));
animationPanel=新建animationPanel();
animationPanel.setSize(新尺寸(750500));
animationPanel.setMinimumSize(新维度(animationPanel.getWidth(),animationPanel.getHeight());
animationPanel.setPreferredSize(新维度(animationPanel.getWidth(),animationPanel.getHeight());
添加(动画面板,BorderLayout.CENTER);
添加(控制面板,BorderLayout.SOUTH);
包装();
setMinimumSize(新尺寸(getWidth(),getHeight());
sliderPanel.setMaximumSize(新维度(sliderPanel.getWidth(),sliderPanel.getHeight());
}
//便利方法
私有void addComponent(GridBagLayout布局、组件组件、int行、int列、插入填充){
GridBagConstraints=新的GridBagConstraints();
constraints.gridx=列;
constraints.gridy=行;
constraints.insets=填充;
布局。设置约束(组件、约束);
滑块面板添加(组件);
}
私有void initLabels(){
windSliderLabel=新的JLabel(“风速”);
角度滑块标签=新的JLabel(“发射角度”);
}
私有void inits滑块(){
风速=新的JS滑翔机(-20,20);
风速.设置主风向间距(10);
风速设置最小间距(5);
风速设定值(真);
风速。设置油漆标签(真);
启动角度=新的JSlider(-15,15);
发射角度。设置主发射间隔(5);
启动角度。设置最小旋转间隔(1);
launchAngle.setPaintTicks(真);
launchAngle.setPaintLabels(真);
}
私有void initButtons(){
startButton=新的JButton(“开始”);
addActionListener(新的StartHandler());
pauseButton=新的JButton(“暂停”);
addActionListener(新的PauseHandler());
exitButton=新JButton(“退出”);
addActionListener(新的ExitHandler());
}
私有void initControlBox(){
controlBox=Box.createHorizontalBox();
controlBox.add(Box.createHorizontalStruct(10));
添加(滑动面板);
添加(Box.createHorizontalstrop(30));
添加(开始按钮);
controlBox.add(Box.createHorizontalStruct(10));
添加(暂停按钮);
添加(Box.createHorizontalGlue());
controlBox.add(Box.createHorizontalStruct(10));
添加(Box.createHorizontalGlue());
添加(exitButton);
controlBox.add(Box.createHorizontalStruct(10));
}
//动作监听器
公共类WindAdjustListener实现ActionListener{
已执行的公共无效操作(操作事件e){
}
}
公共类AngleAdjustListener实现ActionListener{
已执行的公共无效操作(操作事件e){
}
}
公共类StartHandler实现ActionListener{
已执行的公共无效操作(操作事件){
System.out.println(“按下启动”);
setText(“重置”);
重新油漆();
运行动画();
setText(“开始”);
}
}
公共类PauseHandler实现ActionListener{
已执行的公共无效操作(操作事件){
System.out.println(“暂停按下”);
}
}
公共类ExitHandler实现ActionListen
public class StartHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("START Pressed");
startButton.setText("Reset");
repaint();
runAnimation();
startButton.setText("Start");
}
}
do {
//...
} while (fireworks.size() > 0);