所以现在,当你按下它时它只是在屏幕上移动,但我也希望它移动它的腿以便它做一些事情,而不仅仅是站着不动。关于如何做到这一点的任何提示?我知道它会来回移动第二条腿指针,但我不知道该怎么做
Class Stick2:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Stick2 extends JFrame implements ActionListener {
// Declares constants
public static final int FRAME_WIDTH = 500;
private static final int FRAME_HEIGHT = 500;
private static final int FRAME_X_ORIGIN = 150;
private static final int FRAME_Y_ORIGIN = 200;
private static final int BUTTON_WIDTH =80;
private static final int BUTTON_HEIGHT = 30;
JPanel buttonPanel, panel;
MovingBanner2 myBanner;
JButton startButton, stopButton;
Thread thrd;
public static void main(String[] args)
{
Stick2 frame = new Stick2();
frame.setVisible(true);
}
public Stick2(){
Container contentPane= getContentPane();
// Sets Frame
setSize(FRAME_WIDTH,FRAME_HEIGHT);
setResizable(false);
setTitle("Animation");
setLocation(FRAME_X_ORIGIN, FRAME_Y_ORIGIN);
// Sets layout manager
contentPane.setLayout(new BorderLayout(10,0));
buttonPanel = new JPanel();
JButton startButton = new JButton("Start");
startButton.setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
buttonPanel.add(startButton);
startButton.addActionListener(this);
JButton stopButton = new JButton("Stop");
stopButton.setSize(BUTTON_WIDTH,BUTTON_HEIGHT);
buttonPanel.add(stopButton);
stopButton.addActionListener(this);
contentPane.add (buttonPanel, BorderLayout.SOUTH);
// Creates a balloon
myBanner = new MovingBanner2();
panel = myBanner;
panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
contentPane.add(panel, BorderLayout.CENTER);
}
public void actionPerformed (ActionEvent event){
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("Stop")) {
myBanner.stopAnimation();
thrd = null;
}
else {
myBanner.startAnimation();
thrd = new Thread (myBanner);
thrd.start();
}
}
}
Class MovingBanner2:
class MovingBanner2 extends JPanel implements Runnable {
private int x;
private Boolean animate;
int bodyX = 250;
int bodyY1 = 160;
int bodyY2 = 210;
int armHeight = 190;
int armLength = bodyX + 30;
int armLength1 = bodyX - 30;
int legY = 340;
public MovingBanner2() {
x=10;
animate = true;
}
// Draws the String
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
//g.drawString("I love Java", x,50);
g.drawLine(bodyX + x, bodyY1, bodyX + x, bodyY2); //body
g.drawOval(bodyX + x - 15, bodyY1 - 40, 40, 40); //head
g.drawLine(armLength + x,armHeight, armLength1 + x, armHeight); //arms
g.drawLine(bodyX + x, bodyY2, bodyX + 20 + x,legY); //leg
g.drawLine(bodyX + x, bodyY2, bodyX - 20 + x, legY); //leg
}
public void run() {
while (animate) {
changeX();
repaint();
try {Thread.sleep(100); } catch(Exception e){};
}
}
public void changeX() {
if (x <= Stick2.FRAME_WIDTH - 240)
x++;
else x = 10;
}
public void stopAnimation() {
animate = false;
}
public void startAnimation() {
animate = true;
}
}
答案 0 :(得分:3)
这个问题可能有很多答案。我能想到的最好的就是设计某种“循环”。
循环是动画可以运行的已知时间段。在这个例子中,它是1秒。
然后,您需要提供一系列Animatable
个对象,这些对象会随着时间的推移通知周期的变化,这样就可以相应地进行更改。您也可以忽略那些不需要循环的元素的循环。
目的是提供一个单一的动画引擎,它可以一次性更新整个状态,而不是尝试使用多个线程/定时器,这可能会降低系统性能。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestAnimation06 {
public static void main(String[] args) {
new TestAnimation06();
}
public TestAnimation06() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Animatable {
public void update(float progress);
}
public class AnimationEngine {
private List<Animatable> animations;
private int cycleTime = 1000;
private long startTime = -1;
public AnimationEngine() {
animations = new ArrayList<>(25);
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long duration = System.currentTimeMillis() - startTime;
float progress = (float)duration / (float)cycleTime;
if (duration >= cycleTime) {
progress = 1f;
startTime = System.currentTimeMillis();
}
for (Animatable animatable : animations) {
animatable.update(progress);
}
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
public void add(Animatable animatable) {
animations.add(animatable);
}
}
public class TestPane extends JPanel {
private AnimationEngine engine;
public TestPane() {
setLayout(null);
engine = new AnimationEngine();
Legs legs = new Legs();
Walker walker = new Walker(legs);
engine.add(legs);
engine.add(walker);
walker.setSize(walker.getPreferredSize());
add(walker);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class Walker extends JPanel implements Animatable {
private int speed = 2;
public Walker(Legs legs) {
setLayout(new GridBagLayout());
add(legs);
}
@Override
public void update(float progress) {
Container parent = getParent();
int width = parent.getWidth();
int xPos = getX() + speed;
if (xPos <= 0) {
speed *= -1;
xPos = 0;
} else if (xPos + getWidth() >= width) {
speed *= -1;
xPos = width - getWidth();
}
System.out.println(xPos);
setLocation(xPos, (parent.getHeight() - getHeight()) / 2);
repaint();
}
}
public class Legs extends JPanel implements Animatable {
private float frameProgress;
public Legs() {
setOpaque(false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(25, 50);
}
@Override
public void update(float progress) {
frameProgress = progress;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(Color.BLACK);
g.drawLine(width / 2, 0, (int)(width * frameProgress), height);
g.drawLine(width / 2, 0, width - (int)(width * frameProgress), height);
}
}
}