因此,我正在创建一个基本的应用程序,我希望在屏幕底部有一个JLabel,从左下角开始,在设定的时间内移动到右下角,动画风格,并在中心有一个静态图像。为此,我使用BorderLayout创建了一个带有JPanel的JFrame。在BorderLayout.Center中添加了一个带有ImageIcon的JLabel,在BorderLayout.South中添加了一个JPanel。我的代码虽然编写得很匆忙,也很不漂亮,但它是:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.BorderFactory;
public class GameWindow extends JPanel{
private static JLabel mainWindow, arrowLabel, arrowBox;
protected static JFrame frame;
protected static JPanel arrows;
public static int x = 600;
public GameWindow(){
mainWindow = new JLabel("Center");
arrowLabel = new JLabel("Moving");
arrows = new JPanel();
arrows.setSize(600, 100);
arrows.setLayout(null);
arrowBox = new JLabel("");
arrowBox.setBounds(0, 0, 150, 100);
arrowBox.setPreferredSize(new Dimension(150, 100));
arrowBox.setBorder(BorderFactory.createLineBorder(Color.black));
arrows.add(arrowBox);
this.setSize(600,600);
this.setLayout(new BorderLayout());
this.add(mainWindow, BorderLayout.CENTER);
this.add(arrows, BorderLayout.SOUTH);
}
public static void main(String[] args)
{
GameWindow g = new GameWindow();
frame = new JFrame("Sword Sword Revolution");
frame.add(g);
frame.setSize(600,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Timer t = new Timer(1000, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
arrows.add(arrowLabel);
arrowLabel.setBounds(x, 100, 100, 100);
x-=50;
arrows.repaint();
frame.repaint();
}
});
t.start();
}
对于Swing应用程序来说,线程的使用完全是错误的。您不应该尝试在后台线程中添加或删除组件,而应该使用Swing计时器在Swing事件线程上执行此操作。
还有,你说:
我想在屏幕底部有一个滚动的JLabel
为了澄清,我希望在屏幕底部的最右角有一个JLabel,然后在swing计时器中,JLabel将逐渐向左移动,直到它离开屏幕。如果我可以让setLocation工作,基本前提是将变量x设置为600,然后每秒将x减量50,然后在屏幕上的新位置重新绘制JLabel。基本动画。
我将为屏幕底部创建一个JPanel,用于保存JLabel或通过重写其PaintComponent(...)
方法来显示不使用JLabel的图像。如果您将它用作容器,那么是的,它的布局应该是null,但是GUI的其余部分不应该使用null布局。Swing计时器只需更改JLabel的位置,然后在其JPanel/Container上调用repaint()
。如果采用后一种方法,您将使用g.drawimage(myImage,x,y)
在JPanel的PaintComponent(...)
方法中绘制图像,定时器将更改x和/或y,并调用绘制JPanel的repaint()
。
另外,您可能不想一直在计时器中添加JLabel,而是简单地移动GUI中已经显示的JLabel。
编辑4
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.EnumMap;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class AnimateExample extends JPanel {
public static final String DUKE_IMG_PATH =
"https://duke.kenai.com/iconSized/duke.gif";
private static final int PREF_W = 800;
private static final int PREF_H = 800;
private static final int TIMER_DELAY = 20;
private static final String KEY_DOWN = "key down";
private static final String KEY_RELEASE = "key release";
public static final int TRANSLATE_SCALE = 3;
private static final String BACKGROUND_STRING = "Use Arrow Keys to Move Image";
private static final Font BG_STRING_FONT = new Font(Font.SANS_SERIF,
Font.BOLD, 32);
private EnumMap<Direction, Boolean> dirMap =
new EnumMap<AnimateExample.Direction, Boolean>(Direction.class);
private BufferedImage image = null;
private int imgX = 0;
private int imgY = 0;
private int bgStringX;
private int bgStringY;
public AnimateExample() {
for (Direction dir : Direction.values()) {
dirMap.put(dir, Boolean.FALSE);
}
try {
URL imgUrl = new URL(DUKE_IMG_PATH);
image = ImageIO.read(imgUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
new Timer(TIMER_DELAY, new TimerListener()).start();
// here we set up our key bindings
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
for (final Direction dir : Direction.values()) {
// for the key down key stroke
KeyStroke keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0,
false);
inputMap.put(keyStroke, dir.name() + KEY_DOWN);
actionMap.put(dir.name() + KEY_DOWN, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
dirMap.put(dir, true);
}
});
// for the key release key stroke
keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0, true);
inputMap.put(keyStroke, dir.name() + KEY_RELEASE);
actionMap.put(dir.name() + KEY_RELEASE, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
dirMap.put(dir, false);
}
});
}
FontMetrics fontMetrics = getFontMetrics(BG_STRING_FONT);
int w = fontMetrics.stringWidth(BACKGROUND_STRING);
int h = fontMetrics.getHeight();
bgStringX = (PREF_W - w) / 2;
bgStringY = (PREF_H - h) / 2;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setFont(BG_STRING_FONT);
g.setColor(Color.LIGHT_GRAY);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(BACKGROUND_STRING, bgStringX, bgStringY);
if (image != null) {
g.drawImage(image, imgX, imgY, this);
}
}
private class TimerListener implements ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e) {
for (Direction dir : Direction.values()) {
if (dirMap.get(dir)) {
imgX += dir.getX() * TRANSLATE_SCALE;
imgY += dir.getY() * TRANSLATE_SCALE;
}
}
repaint();
};
}
enum Direction {
Up(KeyEvent.VK_UP, 0, -1), Down(KeyEvent.VK_DOWN, 0, 1), Left(
KeyEvent.VK_LEFT, -1, 0), Right(KeyEvent.VK_RIGHT, 1, 0);
private int keyCode;
private int x;
private int y;
private Direction(int keyCode, int x, int y) {
this.keyCode = keyCode;
this.x = x;
this.y = y;
}
public int getKeyCode() {
return keyCode;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
private static void createAndShowGui() {
AnimateExample mainPanel = new AnimateExample();
JFrame frame = new JFrame("Animate Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
它将创建这个GUI:
我正在用Java编写一个游戏,我开始使用drawRect()方法来表示玩家、敌人和射击。一切都很好。然后我决定试着装腔作势。我发现自己在创造。每个对象的png图像,并使用Graphics2D drawImage()方法。一切开始放缓。有没有其他方法可以加快这一进程? 我的动画基于摆动计时器 有关于动画的提示或教程吗?谢谢
我一直在使用Swing编写一个简单的动画,其中有一个JFrame,只要JFrame收到鼠标点击,就会开始一个涟漪动画。我使用一个内部动画类,该类为每个动画扩展JPanel,以防同时播放多个动画(我不知道这是否是最好的方式)。当我单击时,我向JFrame添加一个新动画,并将单击的坐标传递给动画。但是,动画重绘/绘制组件方法不起作用。在我的理解中,repaint应该调用paint/paintCompo
问题内容: 我从来没有能够使Java 6启动屏幕正常工作。 我已经尝试了所有我能想到的。我的manifest.mf包含: 我将文件“ 放在源代码树的根目录中,并验证它是否已放入生成的.jar文件的根目录中。我还在不同的地方尝试过,再次确认其在jar中的位置,并将路径放入SplashScreen-Image中。 它永远不会出现。 尝试在运行时获取启动屏幕失败: 飞溅对我而言始终为空。 关于我在这里缺
问题内容: 我想在应用程序中显示GIF动画图像。我发现,Android本身并不支持动画GIF的困难方式。 但是,它可以使用AnimationDrawable显示动画: 开发>指南>图像和图形> Drawables概述 该示例使用在应用程序资源中另存为帧的动画,但是我需要直接显示动画gif。 我的计划是将动画GIF分解为帧,并将每个帧作为可绘制对象添加到AnimationDrawable中。 有谁知
所以我在谷歌上搜索了这个,但我能在上面找到任何东西:我在代码中调用了这个方法 然后,我添加了一个JProgressBar,称为进度条,并在单击GUI上的按钮时调用此代码: Progresslabel只是一个显示进度的标签。现在,当我这样做时,进度条显示如下: http://i.imgur.com/gXp5ByH.png 与其他应用程序上的情况不同: http://i.imgur.com/M61Cd
动画剪辑 动画剪辑是 Unity 动画系统的核心元素。Unity 不仅支持从外部源导入动画,而且支持在编辑器的动画视图中创建和编辑动画(剪辑)。 从外部源导入动画 从外部源导入的动画剪辑可能包括: 动作捕捉工作室捕捉的人形动画 设计师通过外部 3D 程序(例如 3D Max 或 Maya)创建的动画 第三方的动画集合库(例如来自 Unity Asset store) 导入的单个时间线等分切割为多个